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
queryCollectionpatterns
The exact mechanisms for consuming data collections in Markdown components will be discussed in future releases.
Page Collections vs Data Collections
| Feature | Page Collections | Data Collections |
|---|---|---|
| Type | 'page' (default) | 'data' |
| Content | Markdown files (.md) | JSON files (.json) |
| Schema | defaultPageSchema (forced) | Custom Zod schema (optional) |
| Navigation | Appears in nav/menus | Hidden from nav/menus |
| Purpose | Documentation pages | Structured data for components |
| Query | queryCollection() with page fields | queryCollection() 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
| Property | Required | Description |
|---|---|---|
type | Yes | Must be 'data' for data collections |
source | Yes | Same as page collections (bundled or remote) |
schema | No | Custom Zod schema for validation |
navigation | No | Omit or set to false (data collections don't appear in navigation) |
frontpage | No | Not 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 configurationscolor.json- Color palette definitionslogo.json- Logo asset referencestypography.json- Typography scales and tokensprinciples.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:
- Component integration patterns - Standard ways to consume data in MDC components
- Type generation - Auto-generate TypeScript types from schemas
- Data transformations - Pre-processing pipelines for imported data
- Hybrid collections - Collections with both pages and data
Adding a Data Collection
- Define in collections.ts:
myData: {
type: 'data',
source: {
repository: 'https://github.com/org/repo',
include: 'data/**/*.json'
},
schema: z.object({
// Define your structure
})
}
- Run build - Collection is automatically integrated:
- ✅ Queryable via
queryCollection('myData') - ✅ Filtered from navigation
- ✅ Validated against schema (if provided)
- ✅ Queryable via
- 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.