Search documentation

Search documentation

Pages

Pages Overview

Understand pages, slugs, blocks, previews, and published delivery.

Pages in one minute#

A page is the CMS record behind a website URL. It gives editors a place to choose a name, URL, language, navigation settings, layout, and an ordered set of blocks. Your application fetches the published page and decides how those blocks look in React.

The page delivery flow
Editor creates a page
  -> adds or arranges blocks
  -> saves a draft
  -> reviews it in preview
  -> publishes it
  -> website fetches the published page by URL
  -> PageRenderer renders the blocks

For example, a page called About us might be reached at /about and contain a hero, team list, and contact call to action. The editor can change copy or block order without changing the route code. A developer changes React components when the visual design needs to change.

What Contoprix delivers#

The JavaScript SDK returns a ContoprixPage object. These are the fields most applications use first:

FieldExampleWhat it is for
pageId"8f..."Stable ID. Preview requests use this ID.
name"About us"Editor-facing page name.
slug"about-us"The page's stored slug.
languageCode"en"The language of the delivered content.
pageType"standard"A page classification chosen in the CMS.
blocks[...]Main blocks, including their order and data.
breadcrumbs[...]Available when the page has breadcrumbs enabled.
navigation{ hideHeader: false }Page-level navigation preferences.
layout{ header, footer }Optional global header/footer blocks.
regionLayout{ grid, regions }Optional multi-region layout definition.

A block has an ID, a kind, a component code, a sortOrder, and its data.

Block kindMain dataTypical use
componentsettingsA reusable visual component such as a hero.
content-singlecontentOne selected content entry.
content-listcontentsA list of selected content entries.
formform referenceA placement for a published form.

For content blocks, values are inside entry.data. Do not expect entry.title or entry.body to exist at the top level.

Reading a content-list block
type ArticleData = {
  title?: string;
  summary?: string;
};

const entries = block.contents ?? [];

for (const entry of entries) {
  const article = entry.data as ArticleData;
  console.log(article.title);
}

Page URL, stored slug, and route path#

These terms are related but not always identical:

  • Stored slug is the short value saved on the page record, such as about-us.
  • Route path is the full public URL path, such as /company/about-us for a nested page.
  • Browser URL is the full address, such as https://example.com/company/about-us.

When the frontend fetches a page, use the public route path. The SDK accepts a leading slash and safely encodes each path segment.

Example
CMS page slug:          about-us
Nested public path:     /company/about-us
Frontend request path:  /company/about-us

The home page is special: use client.pages.get() or fetch the route /. See Routing for a complete Next.js example.

How layout works#

A page can use a basic single-column layout or a published Page Layout with regions such as main, sidebar, or footer-callout.

When a region layout is present, each block can have a regionCode. PageRenderer creates a grid from the layout and renders each block in its matching region. Without a region layout, it renders the page's blocks in sortOrder.

Global header and footer pages can also be included in page.layout. PageRenderer renders them before and after the main regions. A page's navigation settings can hide either region.

components/contoprix/ContoprixRenderer.tsx
"use client";

import { PageRenderer } from "@contoprix/react/client";
import type { ContoprixPage } from "@contoprix/types";

import components from "./components";
import { schemas } from "./schema";

export function ContoprixRenderer({ page }: { page: ContoprixPage }) {
  return <PageRenderer page={page} components={components} schemas={schemas} />;
}

PageRenderer sorts blocks, handles header/main/footer rendering, and isolates render failures with error boundaries. It still needs your component registry to know how a block code should look.

CMS pages versus dynamic content routes#

Use a CMS page when an editor needs to choose the layout and block order for one URL: a home page, About page, campaign page, or contact page.

Use a dynamic frontend route when many URLs share one layout and only the record data changes: /blog/[slug], /products/[slug], or /authors/[slug].

These patterns work well together. For example, /blog can be a CMS page with an article-list block, while /blog/[slug] is a dynamic route that renders one article entry.

The editorial lifecycle#

  1. An editor creates the page and configures its name, slug, page type, layout, SEO, navigation, and access settings.
  2. They add or edit blocks in page content. Saving creates a draft version.
  3. Preview reads the draft through the preview API.
  4. Publishing validates the draft, copies it to the published version, and makes it available through the delivery API.
  5. The frontend fetches published content only.

Important

A successful save does not make a change public. Public delivery requires a published page content version for the requested language.

A simple first page#

  1. Create a standard page named About us with slug about-us.
  2. Keep the default layout unless you already need regions.
  3. Add a component block with code hero_banner.
  4. Add a second component or content-list block.
  5. Add hero_banner to the React component registry.
  6. Preview the page, then publish it.
  7. Visit /about-us in your website.

If the page loads but a block is missing, first check whether the block's component code exactly matches a key in the frontend registry.

Next steps#

  • Create a Page: create and configure a page in the CMS.
  • Routing: map website URLs to delivery requests.
  • Dynamic Pages: build repeating article, product, or profile routes.
  • Publishing: understand drafts, versions, publishing, and cache refresh.
  • Visual Builder Setup: connect delivered blocks to React components.