⚠️ Work in progress — createCMS is pre-1.0 and not production-ready (not tested in production). Expect breaking changes.
createCMS
Guides

Use with Next.js

Mount the CMS router, read content in Server Components, and revalidate on publish.

This guide wires @createcms/core into a Next.js App Router project. It assumes you have created a CMS instance (see Quickstart).

Mount the router

cms.router exposes a handler you bind to a catch-all route. The CMS serves every endpoint under basePath (default /api/cms):

app/api/cms/[[...rest]]/route.ts
import { cms } from '@/lib/cms';

const { handler } = cms.router;
export const GET = handler;
export const POST = handler;

Read content in a Server Component

Call the typed API directly on the server. No client fetch is needed for published content:

app/[slug]/page.tsx
import { cms } from '@/lib/cms';

export default async function Page({ params }: { params: Promise<{ slug: string }> }) {
  const { slug } = await params;
  const { variants } = await cms.api.pages.getPublishedContent({
    query: { slug: `/${slug}` },
  });
  // render variants[0].tree (see Render content)
}

Revalidate on publish

Pass onRevalidate to createCMS to receive an event whenever content changes, then revalidate paths or tags. For revalidation triggered from outside the app (a webhook), mount createRevalidateHandler:

app/api/revalidate/route.ts
import { createRevalidateHandler } from '@createcms/core/next';

export const POST = createRevalidateHandler({
  secret: process.env.CMS_REVALIDATE_SECRET!,
});

The handler reads the secret from the x-revalidate-secret request header, compares it in constant time, and returns 401 on a mismatch. On success it calls revalidatePath for each path and revalidateTag for each tag in the event body. The caller must send the header:

await fetch('https://your-app.com/api/revalidate', {
  method: 'POST',
  headers: { 'x-revalidate-secret': process.env.CMS_REVALIDATE_SECRET! },
  body: JSON.stringify({ paths: ['/'], tags: [] }),
});

To turn variants[0].tree into UI, see Render content.

On this page