Collections

Schema Validators

Define collection schemas with your preferred validator and full type-safety.

Nuxt Content supports defining collection schemas with multiple validators. Out of the box, this includes popular libraries like Zod v3 / v4 and Valibot (examples below). The system is extensible and can support other validators via JSON Schema adapters. Schemas enforce data consistency and drive generated types and Studio forms.

Using Zod v3

Install

pnpm add -D zod zod-to-json-schema
# or
npm i -D zod zod-to-json-schema

Prefer importing z directly from zod.

content.config.ts
import { defineContentConfig, defineCollection, property } from '@nuxt/content'
import { z } from 'zod' // or 'zod/v3' if your setup exposes this subpath

export default defineContentConfig({
  collections: {
    blog: defineCollection({
      type: 'page',
      source: 'blog/*.md',
      schema: z.object({
        title: z.string(),
        description: z.string().optional(),
        date: z.date(),
        draft: z.boolean().default(false),
        tags: z.array(z.string()).optional(),
        image: z.object({
          src: property(z.string()).editor({ input: 'media' }),
          alt: z.string()
        })
      })
    })
  }
})
Dates are serialised as ISO strings under the hood (JSON Schema format: date-time).
The z re-export from @nuxt/content is deprecated and will be removed in a future release. Import z from zod (or zod/v3) instead.

Using Zod v4

Zod v4 provides a native JSON Schema export. No zod-to-json-schema dependency is required.

Install

pnpm add -D zod
# or
npm i -D zod
content.config.ts
import { defineContentConfig, defineCollection, property } from '@nuxt/content'
import { z } from 'zod/v4'

export default defineContentConfig({
  collections: {
    docs: defineCollection({
      type: 'page',
      source: 'docs/**/*.md',
      schema: z.object({
        title: z.string(),
        description: z.string().optional(),
        updatedAt: z.date(),
        draft: z.boolean().optional(),
        tags: z.array(z.string()).optional(),
        hero: z.object({
          image: property(z.string()).editor({ input: 'media' }),
          caption: z.string().optional()
        })
      })
    })
  }
})

Using Valibot

Use Valibot primitives to define your schema.

Install

pnpm add -D valibot @valibot/to-json-schema
# or
npm i -D valibot @valibot/to-json-schema
content.config.ts
import { defineContentConfig, defineCollection, property } from '@nuxt/content'
import { object, string, boolean, array, date, optional } from 'valibot'

export default defineContentConfig({
  collections: {
    docs: defineCollection({
      type: 'page',
      source: 'docs/**/*.md',
      schema: object({
        title: string(),
        description: optional(string()),
        updatedAt: date(),
        draft: optional(boolean()),
        tags: optional(array(string())),
        hero: object({
          image: property(string()).editor({ input: 'media' }),
          caption: optional(string())
        })
      })
    })
  }
})

Choosing a validator

  • Zod v3: battle-tested, rich ecosystem; great DX with re-exported z.
  • Valibot: lightweight and fast; bring your own importer from valibot.

Only install and use the validator you need. Nuxt Content auto-detects supported validators that are installed.

Support for other validators

Nuxt Content converts your collection schema to JSON Schema Draft-07 internally. If your preferred validator can be transformed to Draft-07 (or has a compatible adapter), it can be supported. Currently, Zod (v3 and v4) and Valibot are auto-detected. If you’d like first-class support for another validator, consider opening an issue or PR in the Nuxt Content repository.

Editor metadata (optional)

You can enrich fields for Studio via property(...).editor({ ... }) with both validators. See the Studio docs for mapping details.

Learn how editor metadata maps to form inputs in Studio.