Skip to content
Esc
navigateopen⌘Jpreview

SvelteKit

Generate the client into $lib/server and prerender collection entries from +page.server.ts.

SvelteKit builds with Vite, so the plugin does all the codegen: it regenerates the client before every build and dev-server start, and keeps watching while the dev server runs, so a field added in the Stet UI reaches your types a few seconds later.

You need an organization API key in STET_API_KEY; the quickstart covers creating one.

Install

npm install @stetcms/vite @stetcms/client
pnpm add @stetcms/vite @stetcms/client
yarn add @stetcms/vite @stetcms/client
bun add @stetcms/vite @stetcms/client

Add the plugin

import { stet } from '@stetcms/vite';
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [stet(), sveltekit()],
});

Point the output into $lib/server, so SvelteKit itself refuses to bundle the generated client into browser code:

import { defineStet } from '@stetcms/config';

export default defineStet({ output: 'src/lib/server/stet.gen.ts' });

Read content in +page.server.ts

Server load functions run on the server, so the API key never reaches the browser — and because the client lives in $lib/server, importing it from a component is a build error rather than a leak:

import { stet } from '$lib/server/stet.gen';

import type { PageServerLoad } from './$types';

export const load: PageServerLoad = async () => {
  return { posts: await stet.posts.list() };
};
<script lang="ts">
  import type { PageProps } from './$types';

  let { data }: PageProps = $props();
</script>

{#each data.posts as post (post.id)}
  <a href="/blog/{post.slug}">{post.title}</a>
{/each}

Commit src/lib/server/stet.gen.ts: it contains no secrets, and the project type-checks without a key or a reachable Stet, because the plugin never fails a build over either.

Prerender content routes

Enable prerendering from a server layout, then provide every dynamic route parameter with an entry generator:

export const prerender = process.env.STET_API_KEY !== undefined && process.env.STET_API_KEY !== '';
import { stet } from '$lib/server/stet.gen';

import type { EntryGenerator } from './$types';

export const entries: EntryGenerator = async () => {
  if (process.env.STET_API_KEY === undefined || process.env.STET_API_KEY === '') {
    return [];
  }
  const posts = await stet.posts.list();
  return posts.map((post) => ({ slug: post.slug }));
};

SvelteKit writes the discovered pages during svelte-kit build. A configured content request that fails also fails the build.

The SvelteKit example is this guide as a running app.

Was this page helpful?