Next.js
Generate the typed client with the CLI and prerender Stet content with the App Router.
Next.js does not build with Vite, so codegen runs through the
CLI instead of the plugin. stet generate writes the same
src/stet.gen.ts, and your build script runs it before next build.
You need an organization API key in STET_API_KEY; the
quickstart covers creating one.
Install
npm install @stetcms/client @stetcms/cli server-onlypnpm add @stetcms/client @stetcms/cli server-onlyyarn add @stetcms/client @stetcms/cli server-onlybun add @stetcms/client @stetcms/cli server-only@stetcms/client is what the generated file imports at runtime.
@stetcms/cli does the codegen and works as a dev dependency. server-only
earns its place in step 3.
Configure and generate
npx stet init
npx stet generateinit writes a stet.config.ts; generate fetches your content model and
writes src/stet.gen.ts. Commit the generated file: it contains no secrets,
and with it the project type-checks without a key or a reachable Stet.
Read content in server components
Route every import of the generated client through one module that declares itself server-only:
import 'server-only';
export * from '@/stet.gen';import { stet } from '@/lib/stet';
export default async function Blog() {
const posts = await stet.posts.list();
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}Importing the client from a client component is now a build error instead of an API key in the browser bundle.
List collection entries with generateStaticParams to prerender every content
page during next build:
import { stet } from '@/lib/stet';
export const dynamicParams = false;
export async function generateStaticParams() {
const posts = await stet.posts.list();
return posts.map((post) => ({ slug: post.slug }));
}
export default async function Post({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
const post = await stet.posts.get(slug);
return <h1>{post.title}</h1>;
}Wire it into the build
{
"scripts": {
"build": "stet generate && next build"
}
}Every build now starts from the current content model. For environments that
build without a key, --if-key succeeds and
keeps the committed client instead of failing. When the key is configured,
content failures fail the build rather than publishing missing pages.
The Next.js example is this guide as a running app, wired to a seeded local Stet.