Astro

Astro versions

Orbit parses your content config to build the editing forms. All current majors (2 through 7) are supported — the only thing that changes across them is the config path and where Zod comes from:

Astro Config file Import of z (Zod) Collections
2–4 src/content/config.ts astro:content type: 'content' / type: 'data'
5 src/content.config.ts astro:content loaders (glob, file)
6 & 7 src/content.config.ts astro/zod loaders (glob, file)

All config paths also accept .mjs / .js. Astro 7 changed nothing for content collections vs 6. A v6/v7 config looks like:

import { defineCollection } from "astro:content";
import { glob } from "astro/loaders";
import { z } from "astro/zod";           // ← v6+: Zod moved here

const blog = defineCollection({
  loader: glob({ pattern: "*.md", base: "./src/content/blog" }),
  schema: z.object({ title: z.string(), pubDate: z.date() }),
});

export const collections = { blog };

If you’re on 6 or 7, make sure z is imported from astro/zod — importing it from the old path is the most common reason fields come through as untyped.

Also understood: Zod 4’s top-level formats (z.url(), z.email(), z.uuid(), z.int(), z.iso.date()…), Starlight’s docs collection (docsLoader() + docsSchema(), including extend — editors get title, description, template, draft and sidebar settings), and schemas that read values from your own files (e.g. a default author from a site settings module). Orbit doesn’t run your own modules, so such values just aren’t known to the form — the fields still are.