# Template Pages

The pages in the ecommerce boilerplate and the UI-only rule for changing them


A page combines route handling, data loading, layout, and section rendering. Check the complete user flow when changing its presentation.

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).

## Identify the page type

- Content pages include Home, About, Contact, articles, and policy pages. Their content may come from CMS records or fixtures.
- Collection and detail pages display records such as posts, products, tours, or rooms. They need explicit loading, empty, missing-record, and error behavior.
- Application pages include login, profile, checkout, payment, and confirmation. They depend on authentication or transaction flows as well as layout.

The product seeds a fixed slug set when a Web Builder site is created: `home`, `about`, `contact`, `privacy`, `terms`, `blogs`, `blog`, and `legal` for every site; `products`, `product`, `checkout`, `profile`, `confirmation`, `login`, `register`, and `booking` for `ecommerce`, `restaurant`, and `hotel` types; `tours`, `tour`, and `inquiry` on top of the commerce-style set for `tour`. See [`createWeb`](https://github.com/erxes/erxes/blob/f91e8c6f4714c910a32c6b6e14fe085f6435c89e/backend/plugins/content_api/src/modules/webbuilder/graphql/resolvers/mutations/web.ts#L12-L67). Earlier ecommerce conventions map these to routes such as `app/products/page.tsx`, `app/blog/[id]/page.tsx`, and `app/profile/page.tsx`. The selected template defines which routes exist and whether they use an ID, slug, or other parameter. Builder editability is also template-specific.

## Keep route and data behavior aligned

> [!WARNING]
> **UI-only scope**
>
> For a UI-only change, preserve the route identifier, query variables, pagination, portal context, and section mapping. Inspect the existing `usePage` or server fetcher rather than guessing that a route name maps directly to a CMS slug. Do not touch the data layer.

Use `cpPageList` to list a live site's routes (for example to feed `generateStaticParams`), and `cpCmsPageDetail` to fetch a single page:

```graphql
query CpPageList($language: String, $limit: Int, $cursor: String) {
  cpPageList(language: $language, limit: $limit, cursor: $cursor) {
    totalCount
    pageInfo {
      hasNextPage
      endCursor
    }
    pages {
      _id
      name
      slug
      type
      status
      updatedAt
    }
  }
}
```

Use the [CMS query reference](https://erxes.io/docs/content-plug-cms-next-developers-queries). Treat a missing record differently from a network or authorization error. `cpCmsPageDetail` returns `null` when neither `_id` nor `slug` matches (see the [page queries](https://github.com/erxes/erxes/blob/f91e8c6f4714c910a32c6b6e14fe085f6435c89e/backend/plugins/content_api/src/modules/cms/graphql/queries/page.ts)). Do not render unrelated content when the requested slug is unavailable.

## Check the full page

1. Open the URL directly and reload it.
2. Navigate to it through the site and back through browser history.
3. Test an empty list, a missing record, long content, and a failed request.
4. Check metadata, links, images, and pagination for the selected record.
5. Test authentication and submission behavior for application pages affected by the change.
6. Check fixture/preview mode and live mode if both are supported.

Run the available build and quality checks. Describe any route or data change separately from visual changes in the handoff.

Coordinate editable content and fixed application flows with [Template Pages for Designers](https://erxes.io/docs/content-plug-template-designers-template-pages).

