Collections

Data Collections

How to import and use structured data alongside documentation content.

What Are Data Collections?

Data collections are a special type of collection designed to import structured data (JSON files) from content sources. Unlike page collections which contain Markdown documentation, data collections provide raw data that can be consumed by Markdown components within your documentation pages.

Purpose

Data collections enable content sources to:

  • Import structured data from external repositories or local files
  • Version control data alongside documentation
  • Share data across pages through Nuxt Content's query system
  • Expose data to components via standard queryCollection patterns

The exact mechanisms for consuming data collections in Markdown components will be discussed in future releases.

Page Collections vs Data Collections

FeaturePage CollectionsData Collections
Type'page' (default)'data'
ContentMarkdown files (.md)JSON files (.json)
SchemadefaultPageSchema (forced)Custom Zod schema (optional)
NavigationAppears in nav/menusHidden from nav/menus
PurposeDocumentation pagesStructured data for components
QueryqueryCollection() with page fieldsqueryCollection() with custom fields

Defining a Data Collection

Data collections are defined in collections.ts with type: 'data':

import { z } from 'zod/v4'

export const collectionsRegistry = {
  // ... page collections

  myData: {
    type: 'data',
    source: {
      repository: 'https://github.com/org/repo',
      include: 'data/**/*.json'
    },
    schema: z.object({
      metadata: z.record(z.string(), z.unknown()),
      config: z.record(z.string(), z.unknown()),
      data: z.record(z.string(), z.unknown())
    })
  }
} as const

Key Properties

PropertyRequiredDescription
typeYesMust be 'data' for data collections
sourceYesSame as page collections (bundled or remote)
schemaNoCustom Zod schema for validation
navigationNoOmit or set to false (data collections don't appear in navigation)
frontpageNoNot applicable to data collections

Custom Schemas

Data collections support custom Zod schemas for validation. If omitted, no schema validation is applied.

Example: Design System Data

stylebookData: {
  type: 'data',
  source: {
    repository: 'https://github.com/ontopix/stylebook',
    include: 'packages/content/data/*.json'
  },
  schema: z.object({
    metadata: z.record(z.string(), z.unknown()),
    config: z.record(z.string(), z.unknown()),
    data: z.record(z.string(), z.unknown()),
    artefacts: z.record(z.string(), z.unknown())
  })
}

Each JSON file in packages/content/data/ must match this structure:

{
  "metadata": {
    "version": "1.0.0",
    "updated": "2024-01-15"
  },
  "config": {
    "theme": "light",
    "spacing": "comfortable"
  },
  "data": {
    "items": [...],
    "categories": [...]
  },
  "artefacts": {
    "icons": [...],
    "images": [...]
  }
}

Schema Best Practices

  • Use z.record(z.string(), z.unknown()) for flexible object structures
  • Make fields optional with .optional() if not always present
  • Keep schemas permissive to avoid build failures
  • Document expected structure in comments or separate docs

Querying Data Collections

Data collections are queried using Nuxt Content's standard queryCollection() API:

// Server-side or composable
const items = await queryCollection('myData').all()

// With filters
const filtered = await queryCollection('myData')
  .where('metadata.status', 'published')
  .all()

// Single item
const item = await queryCollection('myData')
  .path('/colors')
  .first()

File Structure

Data collections map JSON files to collection items:

stylebook/packages/content/data/
├── colors.json      → queryCollection('stylebookData').path('/colors')
├── typography.json  → queryCollection('stylebookData').path('/typography')
└── icons.json       → queryCollection('stylebookData').path('/icons')

Each file becomes a queryable item with:

  • path: Derived from file path (e.g., /colors)
  • Custom fields: Based on JSON structure and schema
  • Metadata: Nuxt Content-generated fields (id, stem, etc.)

Example: Real-World Usage

The Ontopix Stylebook uses data collections to import design tokens:

// collections.ts
stylebookData: {
  type: 'data',
  source: {
    repository: 'https://github.com/ontopix/stylebook',
    include: 'packages/content/data/*.json'
  },
  schema: z.object({
    metadata: z.record(z.string(), z.unknown()),
    config: z.record(z.string(), z.unknown()),
    data: z.record(z.string(), z.unknown()),
    artefacts: z.record(z.string(), z.unknown())
  })
}

This imports:

  • avatars.json - Avatar component configurations
  • color.json - Color palette definitions
  • logo.json - Logo asset references
  • typography.json - Typography scales and tokens
  • principles.json - Design principle guidelines

These data files can then be queried and consumed by Vue components embedded in Markdown documentation pages.

Filtering in Runtime

Data collections are automatically filtered out from:

  • Navigation menus and collection grids
  • MCP tools (list-pages, get-page)
  • Search indexes and content navigation
  • LLMs.txt sections for AI crawlers

This ensures data collections remain "invisible" infrastructure that powers components without cluttering documentation navigation.

Limitations

  • No Markdown support: Data collections only accept JSON files
  • No navigation: Data collections cannot appear in nav/menus
  • Component consumption TBD: Exact patterns for component integration are under development
  • Build-time only: Data is fetched at build time, not runtime

Future Directions

Planned enhancements for data collections:

  1. Component integration patterns - Standard ways to consume data in MDC components
  2. Type generation - Auto-generate TypeScript types from schemas
  3. Data transformations - Pre-processing pipelines for imported data
  4. Hybrid collections - Collections with both pages and data

Adding a Data Collection

  1. Define in collections.ts:
myData: {
  type: 'data',
  source: {
    repository: 'https://github.com/org/repo',
    include: 'data/**/*.json'
  },
  schema: z.object({
    // Define your structure
  })
}
  1. Run build - Collection is automatically integrated:
    • ✅ Queryable via queryCollection('myData')
    • ✅ Filtered from navigation
    • ✅ Validated against schema (if provided)
  2. Query in components - Use standard Nuxt Content queries to access data

No additional configuration needed in content.config.ts or nuxt.config.ts - data collections work seamlessly alongside page collections.