Quickstart
Install the Vite plugin, point it at your organization, and go from an empty project to a typed content client in four steps.
Getting from an empty project to typed content is four steps. Everything after that happens on its own: the client regenerates whenever the model changes.
Create an API key
API keys are scoped to an organization. In the Stet app, open Developers → API keys and create one. You need to be an owner or admin of the organization. Copy the key while it is on screen: only its hash is stored, so it is shown once. The authentication reference has the detail.
Export it, along with the origin if you self-host:
export STET_API_KEY="..."
# Only if you self-host. The default is the hosted cloud.
export STET_ORIGIN="https://stet.example.com"Install the packages
npm install @stetcms/vite @stetcms/clientpnpm add @stetcms/vite @stetcms/clientyarn add @stetcms/vite @stetcms/clientbun add @stetcms/vite @stetcms/clientThe plugin generates the client; @stetcms/client is what the generated file
imports at runtime, so both belong in your dependencies.
Add the plugin
import { stet } from '@stetcms/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [stet()],
});That is the whole setup. The plugin writes src/stet.gen.ts before every build
and dev-server start, and keeps watching while the dev server runs, so a field
your content team adds in the UI reaches your types a few seconds later.
Read your content
import { stet } from './stet.gen';
const posts = await stet.posts.list();
const post = await stet.posts.get('hello-world');
post.title;
post.fields.body; // markdown
post.fields.cover?.url; // a whole, public URLThe keys on stet are your organization’s collections and maps, and the fields
on an entry are the ones your content team defined. Both autocomplete.
Add a config file
The plugin runs with no configuration. Add stet.config.ts at your project
root when you want to move the generated file, pin an origin, or declare an
analytics tracking plan:
import { defineStet } from '@stetcms/config';
export default defineStet({
output: 'src/lib/stet.gen.ts',
});
The CLI reads the same file, so stet generate in CI writes exactly where your
dev server does. See the configuration reference
for every option and how they resolve.
Generate without a dev server
CI and one-off scripts do not run Vite. The CLI does the same codegen:
npx stet generate
Where content is read from
The generated client talks to the Stet API from your server, never from a browser. In a framework with server-side data loading, that means a loader, a server function, or a route handler:
import { createServerFn } from '@tanstack/react-start';
import { stet } from './stet.gen';
export const getPosts = createServerFn().handler(() => stet.posts.list());import { stet } from './stet.gen';
export default async function Page() {
const posts = await stet.posts.list();
return <PostList posts={posts} />;
}---
import { stet } from '../stet.gen';
const posts = await stet.posts.list();
---