{"id":31698759,"url":"https://github.com/greenheart/keystatic-sveltekit","last_synced_at":"2026-05-15T01:37:04.047Z","repository":{"id":317452003,"uuid":"1059610440","full_name":"Greenheart/keystatic-sveltekit","owner":"Greenheart","description":"📝 Convenient Keystatic integration for SvelteKit, featuring Markdoc content with interactive Svelte components and a modern editing UX for your entire team.","archived":false,"fork":false,"pushed_at":"2025-09-30T23:57:05.000Z","size":305,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-01T01:11:56.638Z","etag":null,"topics":["cms","integration","keystatic","markdoc","svelte","sveltekit"],"latest_commit_sha":null,"homepage":"https://samuelplumppu.se/blog/keystatic-sveltekit-markdoc","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Greenheart.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-18T17:19:49.000Z","updated_at":"2025-09-30T23:57:08.000Z","dependencies_parsed_at":"2025-10-01T01:13:29.011Z","dependency_job_id":"53a279d2-1267-4214-be08-915b7a34ef61","html_url":"https://github.com/Greenheart/keystatic-sveltekit","commit_stats":null,"previous_names":["greenheart/keystatic-sveltekit"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/Greenheart/keystatic-sveltekit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Greenheart%2Fkeystatic-sveltekit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Greenheart%2Fkeystatic-sveltekit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Greenheart%2Fkeystatic-sveltekit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Greenheart%2Fkeystatic-sveltekit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Greenheart","download_url":"https://codeload.github.com/Greenheart/keystatic-sveltekit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Greenheart%2Fkeystatic-sveltekit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279000701,"owners_count":26082805,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-08T02:00:06.501Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cms","integration","keystatic","markdoc","svelte","sveltekit"],"created_at":"2025-10-08T19:10:40.521Z","updated_at":"2026-05-15T01:37:04.039Z","avatar_url":"https://github.com/Greenheart.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# keystatic-sveltekit\n\nLibrary for integrating the Git-based [Keystatic](https://keystatic.com/) 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](https://samuelplumppu.se/blog/keystatic-sveltekit-markdoc) to learn more about why this is useful, and the background to this project.\n\n```sh\npnpm add keystatic-sveltekit\n```\n\n## Library key features\n\n- Make it easy to integrate a high-quality Git-based CMS with SvelteKit projects.\n\n- 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?\n\n- Supports hot reloading during development to make it simple and enjoyable to edit `keystatic.config.ts` and quickly see the results in the CMS.\n\n## Get started\n\nYou need a SvelteKit project before adding `keystatic-sveltekit`.\n\n```sh\nnpx sv create my-app\n# Alternatively, if you already have a project:\ncd my-app\n```\n\nInstall the required dependencies:\n\n```sh\npnpm add keystatic-sveltekit @keystatic/core react react-dom\n```\n\nAlternatively, if you plan to [only use Keystatic CMS locally during development](#how-to-only-enable-keystatic-cms-during-development):\n\n```sh\npnpm add -D keystatic-sveltekit @keystatic/core react react-dom\n```\n\n### Adding Keystatic CMS in your SvelteKit project\n\nAdd `keystatic.config.ts` to your project root directory:\n\n```ts\n// keystatic.config.ts\nimport { config } from '@keystatic/core'\n\nexport default config({\n  // See https://keystatic.com/docs/configuration\n})\n```\n\nAdd the Vite plugin:\n\n```ts\n// vite.config.ts\nimport { defineConfig } from 'vite'\nimport { sveltekit } from '@sveltejs/kit/vite'\nimport { keystatic } from 'keystatic-sveltekit'\n\nexport default defineConfig({\n  // Register the keystatic plugin before SvelteKit\n  plugins: [keystatic(), sveltekit()],\n})\n```\n\nRegister the Keystatic routes in a [SvelteKit server hook](https://svelte.dev/docs/kit/hooks#Server-hooks). This will serve both the CMS frontend and API routes.\n\n```ts\n// src/hooks.server.ts\nimport { type Handle } from '@sveltejs/kit'\nimport { handleKeystatic } from 'keystatic-sveltekit'\nimport config from '../keystatic.config.ts'\n\nexport const handle: Handle = await handleKeystatic({ config })\n```\n\nYou 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.\n\n---\n\n\u003e [!NOTE]\n\u003e This section should be removed once the upstream Keystatic fixes [issue 366](https://github.com/Thinkmill/keystatic/issues/366)\n\n**Temporary step:** Finally, there is one quirk with Keystatic that we need to address before [this PR](https://github.com/Thinkmill/keystatic/pull/1465) 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](https://keystatic.com/docs/github-mode)) to properly support OAuth redirects. However, when using [local mode](https://keystatic.com/docs/local-mode), this redirect is not necessary and quite disruptive when everything else is hosted on `localhost`.\n\nThere are two workarounds:\n\n1. Change `vite.config.ts` to set `server.host` to `127.0.0.1` to host SvelteKit on both `localhost` and `127.0.0.1`. This is the easy solution, but might cause weird behaviours with redirects from `localhost` to `127.0.0.1` when opening Keystatic.\n2. Use `pnpm patch` ([instructions](https://pnpm.io/cli/patch)) to add [this patch](./patches/@keystatic__core.patch) and implement the same workaround as in the upstream [PR](https://github.com/Thinkmill/keystatic/pull/1465).\n\n---\n\nOnce all steps are completed, you can run `pnpm dev` and access Keystatic CMS at \u003chttp://localhost:5173/keystatic\u003e.\n\nIf you plan to use [GitHub mode](https://keystatic.com/docs/github-mode), follow the guide for further instructions on how to create and configure a GitHub app.\n\nRemember that you can configure GitHub mode for production and still use [local mode](https://keystatic.com/docs/local-mode) during development, by modifying your `keystatic.config.ts` like this:\n\n```ts\n// keystatic.config.ts\nexport default config({\n  storage: import.meta.env.DEV\n    ? {\n        kind: 'local',\n      }\n    : {\n        kind: 'github',\n        repo: 'user/repo',\n      },\n})\n```\n\n### Read content and use it in your SvelteKit project\n\nThe [Keystatic Reader API](https://keystatic.com/docs/reader-api) is a good way to read your content and use it on the server side of SvelteKit.\n\nSee the demo project below to see one way to implement it.\n\n---\n\n## Demo project and Markdoc integration\n\nThe Git repository for [keystatic-sveltekit](https://github.com/Greenheart/keystatic-sveltekit) also includes a demo project showing how to set up `keystatic-sveltekit` and how to use [markdoc-svelte](https://github.com/CollierCZ/markdoc-svelte) to render rich [Markdoc](https://markdoc.dev/) content with support for embedding interactive Svelte components and other useful features.\n\n### Key features\n\n- 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 `pages` content type which could enable block-based content editing.\n- 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.\n- Possibility to embed interactive Svelte components in the Markdoc content, creating rich experiences. This enables flexible and powerful content blocks.\n- Markdoc content validation via schemas to catch errors early. A big advantage over a similar solution like [MDX](https://mdxjs.com/).\n\n### Explore the demo\n\nYou can explore the demo by cloning the Git repo and running the following commands:\n\n```sh\npnpm i\npnpm dev\n```\n\nThen you can visit:\n\n- Demo page: \u003chttp://localhost:5173\u003e\n- CMS: \u003chttp://localhost:5173/keystatic\u003e\n\nTry making changes to posts and see how the live project hot reloads both for configuration changes in `keystatic.config.ts` and when editing posts.\n\n---\n\n## How to only enable Keystatic CMS during `development`:\n\nIf you use the Keystatic `local` storage mode, here's how you enable the CMS only during `development`:\n\n1. Only import and enable the Vite plugin during `dev`:\n\n```ts\n// vite.config.ts\nimport { defineConfig } from 'vite'\nimport { sveltekit } from '@sveltejs/kit/vite'\n\nconst dev = process.env.NODE_ENV === 'development'\n\nexport default defineConfig({\n  plugins: [dev \u0026\u0026 (await import('keystatic-sveltekit')).keystatic(), sveltekit()],\n})\n```\n\n2. Only import and enable the SvelteKit hook during `dev`:\n\n```ts\n// src/hooks.server.ts\nimport { type Handle } from '@sveltejs/kit'\nimport { sequence } from '@sveltejs/kit/hooks'\nimport { dev } from '$app/environment'\n\n// Add your other hooks here\nconst hooks: Handle[] = []\n\n// Only enable Keystatic during development\nif (dev) {\n  // Use dynamic imports to reduce the size of the production build.\n  const config = (await import('../keystatic.config.ts')).default\n  const { handleKeystatic } = await import('keystatic-sveltekit')\n  hooks.push(await handleKeystatic({ config }))\n}\n\nexport const handle = sequence(...hooks)\n```\n\n3. You can also consider moving some dependencies like `keystatic-sveltekit` and `@keystatic/core` to `devDependencies` so they won't be installed for production environments.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgreenheart%2Fkeystatic-sveltekit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgreenheart%2Fkeystatic-sveltekit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgreenheart%2Fkeystatic-sveltekit/lists"}