Library for integrating the Git-based Keystatic CMS with SvelteKit. This allows you to serve the CMS from the same server as your main SvelteKit app. You can read the blog post to learn more about why this is useful, and the background to this project.
pnpm add keystatic-sveltekit-
Make it easy to integrate a high-quality Git-based CMS with SvelteKit projects.
-
This library allows serving Keystatic CMS with the same server as SvelteKit. This improved both development and production builds by removing the need to install and maintain a separate metaframework just for the CMS. If you already use SvelteKit, why not use it for the CMS as well?
-
Supports hot reloading during development to make it simple and enjoyable to edit
keystatic.config.tsand quickly see the results in the CMS.
You need a SvelteKit project before adding keystatic-sveltekit.
npx sv create my-app
# Alternatively, if you already have a project:
cd my-appInstall the required dependencies:
pnpm add keystatic-sveltekit @keystatic/core react react-domAlternatively, if you plan to only use Keystatic CMS locally during development:
pnpm add -D keystatic-sveltekit @keystatic/core react react-domAdd keystatic.config.ts to your project root directory:
// keystatic.config.ts
import { config } from '@keystatic/core'
export default config({
// See https://keystatic.com/docs/configuration
})Add the Vite plugin:
// vite.config.ts
import { defineConfig } from 'vite'
import { sveltekit } from '@sveltejs/kit/vite'
import { keystatic } from 'keystatic-sveltekit'
export default defineConfig({
// Register the keystatic plugin before SvelteKit
plugins: [keystatic(), sveltekit()],
})Register the Keystatic routes in a SvelteKit server hook. This will serve both the CMS frontend and API routes.
// src/hooks.server.ts
import { type Handle } from '@sveltejs/kit'
import { handleKeystatic } from 'keystatic-sveltekit'
import config from '../keystatic.config.ts'
export const handle: Handle = await handleKeystatic({ config })You can also pass in additional configuration like environment variables, which is useful if you have nonstandard names for your environment variables. Refer to the parameters of handleKeystatic() for more info.
Note
This section should be removed once the upstream Keystatic fixes issue 366
Temporary step: Finally, there is one quirk with Keystatic that we need to address before this PR gets merged. Keystatic always redirects to 127.0.0.1 (the loopback address) when visiting the /keystatic admin UI. This is technically necessary when using the GitHub mode) to properly support OAuth redirects. However, when using local mode, this redirect is not necessary and quite disruptive when everything else is hosted on localhost.
There are two workarounds:
- Change
vite.config.tsto setserver.hostto127.0.0.1to host SvelteKit on bothlocalhostand127.0.0.1. This is the easy solution, but might cause weird behaviours with redirects fromlocalhostto127.0.0.1when opening Keystatic. - Use
pnpm patch(instructions) to add this patch and implement the same workaround as in the upstream PR.
Once all steps are completed, you can run pnpm dev and access Keystatic CMS at http://localhost:5173/keystatic.
If you plan to use GitHub mode, follow the guide for further instructions on how to create and configure a GitHub app.
Remember that you can configure GitHub mode for production and still use local mode during development, by modifying your keystatic.config.ts like this:
// keystatic.config.ts
export default config({
storage: import.meta.env.DEV
? {
kind: 'local',
}
: {
kind: 'github',
repo: 'user/repo',
},
})The Keystatic Reader API is a good way to read your content and use it on the server side of SvelteKit.
See the demo project below to see one way to implement it.
The Git repository for keystatic-sveltekit also includes a demo project showing how to set up keystatic-sveltekit and how to use markdoc-svelte to render rich Markdoc content with support for embedding interactive Svelte components and other useful features.
- Posts can be deeply nested, giving more flexibility for how to organise posts and their URLs. A similar config could be used to create a more general
pagescontent type which could enable block-based content editing. - Hot reloading while editing posts gives you rapid live previews. Ideal for viewing both the CMS/code editor and the live project side by side.
- Possibility to embed interactive Svelte components in the Markdoc content, creating rich experiences. This enables flexible and powerful content blocks.
- Markdoc content validation via schemas to catch errors early. A big advantage over a similar solution like MDX.
You can explore the demo by cloning the Git repo and running the following commands:
pnpm i
pnpm devThen you can visit:
- Demo page: http://localhost:5173
- CMS: http://localhost:5173/keystatic
Try making changes to posts and see how the live project hot reloads both for configuration changes in keystatic.config.ts and when editing posts.
If you use the Keystatic local storage mode, here's how you enable the CMS only during development:
- Only import and enable the Vite plugin during
dev:
// vite.config.ts
import { defineConfig } from 'vite'
import { sveltekit } from '@sveltejs/kit/vite'
const dev = process.env.NODE_ENV === 'development'
export default defineConfig({
plugins: [dev && (await import('keystatic-sveltekit')).keystatic(), sveltekit()],
})- Only import and enable the SvelteKit hook during
dev:
// src/hooks.server.ts
import { type Handle } from '@sveltejs/kit'
import { sequence } from '@sveltejs/kit/hooks'
import { dev } from '$app/environment'
// Add your other hooks here
const hooks: Handle[] = []
// Only enable Keystatic during development
if (dev) {
// Use dynamic imports to reduce the size of the production build.
const config = (await import('../keystatic.config.ts')).default
const { handleKeystatic } = await import('keystatic-sveltekit')
hooks.push(await handleKeystatic({ config }))
}
export const handle = sequence(...hooks)- You can also consider moving some dependencies like
keystatic-sveltekitand@keystatic/coretodevDependenciesso they won't be installed for production environments.
MIT