Recipes
Dynamic CMS routes
Generate a static page for every CMS slug at build time with generateStaticParams.
Legacy CMS
This recipe uses the legacy Projects CMS (listPages / getPage). For a Site, build the params from
listSitePages — see step 6 of the Public website path.
A [slug]/page.tsx route that pre-renders every CMS page in your project.
The route
// app/[slug]/page.tsx
import { getPage, listPages } from '@uidu/client';
import { PageBlocks } from '@uidu/react';
import { notFound } from 'next/navigation';
import { client } from '@/lib/uidu';
import { Hero, Feature, ContactForm } from '@/components/blocks';
export async function generateStaticParams() {
const pages = await listPages(client, {
projectId: process.env.UIDU_PROJECT_ID!,
first: 200,
});
return pages.map((p) => ({ slug: p.slug }));
}
export default async function CmsPage({
params,
}: {
params: Promise<{ slug: string }>;
}) {
const { slug } = await params;
const page = await getPage(client, {
projectId: process.env.UIDU_PROJECT_ID!,
slug,
});
if (!page) notFound();
return (
<PageBlocks
pageBlocks={page.pageBlocks}
components={{
Hero,
feature1: Feature,
ContactForm,
}}
/>
);
}Why this works
listPagesreturns every page slug in the project — that's whatgenerateStaticParamsneeds.getPageis called once per slug at build time. Next.js caches the result per route.<PageBlocks>looks up each block'stemplateBlock.shortnamein yourcomponentsmap and renders the matching component with the block'sfieldValues.
Add a sitemap
// app/sitemap.ts
import { listPages } from '@uidu/client';
import { client } from '@/lib/uidu';
export default async function sitemap() {
const pages = await listPages(client, {
projectId: process.env.UIDU_PROJECT_ID!,
first: 500,
});
return pages.map((p) => ({
url: `https://example.com/${p.slug}`,
lastModified: p.updatedAt,
}));
}Add ISR revalidation
If you want the page to refresh without a redeploy, set a revalidation interval:
export const revalidate = 60; // secondsFor event-driven invalidation, configure a webhook in your uidu workspace to hit /api/revalidate?path=/<slug> and call revalidatePath from there.
For more than ~500 pages, walk every page with the paginate() helper.