# Template Sections

Change how existing template sections look without breaking their data bindings


A section is a reusable part of a page (a Hero, article list, gallery, or contact form) rendered from one entry in the page's `pageItems` list. Its presentation must stay compatible with the content the template receives.

Template paths and editor controls depend on the separate template repository. Confirm them in your checkout; see [what the product defines](https://erxes.io/docs/content-plug-template-developers-introduction).

## Separate the CMS data shape from the component's props

The [Page schema](https://github.com/erxes/erxes/blob/f91e8c6f4714c910a32c6b6e14fe085f6435c89e/backend/plugins/content_api/src/modules/cms/graphql/schemas/page.ts) exposes `PageItem.type` and a JSON `config`. It does not constrain `config` to a particular Hero or gallery schema, so a template must validate that data before treating it as typed component props. On Web Builder pages the same items are `WebPageItem`s carrying `contentType`/`contentTypeId` instead of the CMS `objectType`/`objectId`; the deployer copies each item into `data/pages/*.json` under the `objectType`/`objectId` key names. See [`buildPageConfigs`](https://github.com/erxes/erxes/blob/f91e8c6f4714c910a32c6b6e14fe085f6435c89e/backend/plugins/content_api/src/modules/webbuilder/utils/utils.ts#L79-L91).

For example, a template might define these component types:

```ts
type HeroConfig = {
  title: string;
  description?: string;
  imageUrl?: string;
  imageAlt?: string;
  primaryCta?: { label: string; href: string };
};

type HeroProps = {
  config: HeroConfig;
};
```

These names are illustrative template types, not GraphQL fields guaranteed by erxes. At the data boundary, validate unknown configuration using the selected template's established validation approach before passing it to the component. Avoid a broad `any` type that hides missing or incompatible values.

## Preserve registration and identity

Locate the mapping from the item's `type` to a component, including any separate fixture, preview, and CMS renderers. Common locations include `app/page.tsx`, `lib/renderSections.tsx`, and `lib/usePage.tsx`, but your template may differ.

> [!WARNING]
> **UI-only scope**
>
> For a UI-only assignment, change the existing component's presentation and keep its identifier, inputs, and data hooks intact. Do not rename a `pageItems[].type` value or alter the fetch that supplies it. For a planned new section, update every supported renderer, editor definition, validator, and fixture together.

## Render every state

Support missing optional text, long headings, empty collections, and failed requests. Use the existing asset and route helpers. Give images appropriate alternative text and keep links valid when content is unavailable.

A section that lists linked records (for example, a `type` that references posts through `objectType`/`objectId` or `contentType`/`contentTypeId`) needs a loading state, an empty state, and a bounded list. Keep data fetching and secret credentials on the server where required; a section needing browser state can receive a safe, serialized data subset. Follow the [CMS rendering examples](https://erxes.io/docs/content-plug-cms-next-developers-ssr) for integration behavior.

For builder-managed pages, `cpWebPage` returns the same section list scoped to a `webId` (see the [WebPage schema](https://github.com/erxes/erxes/blob/f91e8c6f4714c910a32c6b6e14fe085f6435c89e/backend/plugins/content_api/src/modules/webbuilder/graphql/schemas/webPage.ts)):

```graphql
query CpWebPage($slug: String, $webId: String, $language: String) {
  cpWebPage(slug: $slug, webId: $webId, language: $language) {
    _id
    name
    slug
    pageItems {
      _id
      name
      type
      content
      order
      contentType
      contentTypeId
      config
    }
  }
}
```

## Check the section

Use a known fixture, an empty fixture, and representative live content. Check the component in every supported rendering mode and on more than one page if it is shared. Check responsive layout, keyboard controls, image sizing, and loading/error feedback.

Use the [designer section catalog](https://erxes.io/docs/content-plug-template-designers-template-sections) to agree on editable fields and states, then continue with [Template Pages](https://erxes.io/docs/content-plug-template-developers-template-pages).

