Rendering

Render cmssy content in your app

One catch-all route turns every published page - blocks, layout, SEO and locale - into server-rendered HTML on your own Next.js frontend.

Rendering

The catch-all route, page component, metadata, layout, localized routing and ISR revalidation.

The catch-all route

A cmssy workspace stores content; your app renders it. One optional catch-all route - app/[[...path]]/page.tsx - maps every published slug (and its locale prefix) to a page. createCmssyPage fetches the page for the current path, matches each block to your registered component and renders it on the server.

The catch-all is statically renderable: it never reads searchParams or headers(), so ISR stays on. Draft preview still works per-request through draftMode().

import { createCmssyPage } from "@cmssy/next/server";
import { cmssy } from "@/cmssy.config";
import { blocks } from "@/cmssy/blocks";

export const revalidate = 3600;

// The public route stays static. A verified editor request is rewritten by the
// middleware onto app/cmssy-edit/[[...path]], mounted with createCmssyEditPage.
export default createCmssyPage(cmssy, blocks);

Page component & config

createCmssyPage(config, blocks, options?) returns an async server component. config comes from defineCmssyConfig; blocks is the array of defineBlock definitions the SDK matches by type. Pass { editor } to mount the visual editor on the preview route, or { path } to pin a single-page route.

import { defineCmssyConfig } from "@cmssy/next";

// Pass process.env raw: defineCmssyConfig validates at startup and names any
// variable you are missing. A `?? ""` fallback would hide that, and the error
// would surface later, somewhere unrelated.
//
// This module reads server env. Never import a VALUE from it (or from a module
// that imports it) in a "use client" component - types are erased, values drag
// process.env into the browser bundle.
export const cmssy = defineCmssyConfig({
  org: process.env.CMSSY_ORG_SLUG,
  workspaceSlug: process.env.CMSSY_WORKSPACE_SLUG,
  draftSecret: process.env.CMSSY_DRAFT_SECRET,
});

What this section covers

The catch-all route, page component, metadata, layout, localized routing and ISR revalidation.

The wiring, one concern per page. Read them in order the first time; after that, jump.

  • Routes and pages - config, middleware, the public catch-all and the edit route. Copy it whole: the pieces depend on each other.
  • Layouts - header and footer as editable blocks, and why leaving out the editable wrapper breaks silently.
  • Draft preview - the three ways to see unpublished content, and the secret behind each.
  • i18n - locales, URL prefixes, and what renders when a translation is missing.
  • SEO - metadata, sitemap and robots, all owned by your app.
  • Scripts - analytics and third-party tags, and the CSP that blocks them.

One thing to carry into all of them: the SDK renders blocks and mounts the editor, and stops there. Metadata, the sitemap, locale helpers and the member session are your app's own code - see the delivery API for what you query directly.