← Back to site

Testing Keystatic Schema

Keystatic’s schema in keystatic.config.ts lives alongside Astro’s Zod schema in src/content/config.ts. The two have no shared type, so edits to one can silently drift from the other — and editors only notice when they open the admin UI and an entry fails to load.

The Vitest suite at src/utils/__tests__/keystaticSchema.test.ts closes that loop by running every content file through Keystatic’s Reader API — the same code path the admin UI uses. If a file would break in the admin, the test fails.

Running

npm test                                                 # full suite (ran pre-build too)
npx vitest run src/utils/__tests__/keystaticSchema.test.ts  # only these tests

What the suite checks

  1. Config loads — imports keystatic.config.ts and asserts it exports a valid config. Catches syntax errors and broken imports from the MDX component registry at src/keystatic/mdxComponents.tsx.

  2. Reader API resolves every entry — for each of the 18 Keystatic collections, calls reader.collections[name].list() then read(slug, { resolveLinkedFiles: true }) for every file. A null return or thrown error means Keystatic can’t parse the frontmatter against its schema.

  3. Astro ↔ Keystatic parity — for each collection in src/content/config.ts, asserts at least one Keystatic collection writes to src/content/<collection>/.

When it fires

  • A field renamed in keystatic.config.ts but not in src/content/config.ts (or vice versa).
  • A required field added to Keystatic without migrating existing content.
  • MDX body content with constructs Keystatic can’t parse (e.g. import statements). The src/components/mdx/ barrel is wired globally via <Content components={mdxComponents} /> in the slug pages, so bare tags like <Button> resolve without imports.
  • Referenced images missing from the collection’s asset directory.

What it doesn’t catch

  • UI regressions (button clicks, form behavior).
  • GitHub storage mode issues (OAuth, commits, pushes).
  • Cloudflare adapter runtime errors.

For those, manual smoke-testing against npm run dev:admin is still the fallback. Playwright E2E against /keystatic is possible but not currently set up — the admin UI has no published selectors/test-ids, so it would be flaky.

After schema changes

Always update both keystatic.config.ts and src/content/config.ts in the same commit, then run npm test. If the suite goes red, the error messages list each broken file and the mismatched field — fix the content or align the schemas, then re-run.