Content Schemas
Overview
All content schemas are defined in layer/content.collections.ts using Zod. Each schema maps to a Nuxt Content collection.
The layer exports base schemas that your app's content.config.ts imports and uses when defining collections.
Collections Summary
| Collection | Schema | Type | Route Prefix | Description |
|---|---|---|---|---|
pages | basePageSchema | page | / | Landing pages |
docs | basePageSchema | page | /docs | Documentation |
changelog | baseChangelogSchema | page | — | Changelog entries |
references | baseReferencesSchema | data | — | Academic references |
glossary | baseGlossarySchema | data | — | Glossary terms |
faq | baseFaqSchema | data | — | FAQ items |
config | baseConfigSchema | data | — | Site configuration |
navigation | baseNavigationSchema | data | — | Navigation structure |
team | baseTeamSchema | data | — | Team members |
basePageSchema
Used by pages and docs collections. Defines page metadata for both landing pages and documentation.
basePageSchema = z.object({
label: z.string().optional(),
title: z.string(),
description: z.string().optional(),
excerpt: z.string().optional(),
image: z.string().optional(),
navigation: z.boolean().optional(),
layout: z.string().optional(),
hero: z.boolean().optional().default(true),
links: z.array(z.object({
label: z.string(),
icon: z.string().optional(),
to: z.string(),
target: z.string().optional(),
})).optional(),
})
baseConfigSchema
Site-level business configuration. Loaded from content/config/site.yml.
baseConfigSchema = z.object({
business: z.object({
name: z.string(),
legalName: z.string(),
foundingYear: z.number(),
logo: z.string(),
mission: z.string(),
}),
socials: z.record(z.string(), z.string()).optional(),
})
baseNavigationSchema
Navigation structure for header, footer, and banner. Loaded from content/config/navigation.yml.
baseNavigationSchema = z.object({
banner: bannerSchema, // See bannerSchema below
header: z.object({
title: z.string().optional(),
socials: z.record(z.string(), z.string()).optional(),
navigation: z.array(navigationLinkSchema).optional(),
showSearch: z.boolean().optional().default(true),
showColorMode: z.boolean().optional().default(true),
}),
footer: z.object({
columns: z.array(navigationColumnSchema).optional(),
bottom: z.array(navigationLinkSchema).optional(),
}),
})
// Banner schema
bannerSchema = z.object({
title: z.string().optional(),
icon: z.string().optional(),
color: z.enum(['primary', 'neutral', 'success', 'warning', 'error']).optional(),
to: z.string().optional(),
target: z.string().optional(),
close: z.boolean().optional(),
actions: z.array(z.object({
label: z.string(),
to: z.string().optional(),
icon: z.string().optional(),
color: z.string().optional(),
size: z.string().optional(),
variant: z.string().optional(),
})).optional(),
})
// Reusable navigation link
navigationLinkSchema = z.object({
label: z.string(),
to: z.string(),
icon: z.string().optional(),
target: z.string().optional(),
})
baseChangelogSchema
Changelog entries with version tracking and author attribution.
baseChangelogSchema = z.object({
label: z.string(),
version: z.string(),
date: z.string().optional(),
title: z.string(),
description: z.string().optional(),
excerpt: z.string().optional(),
image: z.string().optional(),
author: z.string().optional(), // team member slug
})
baseTeamSchema
Team member profiles for author attribution and team pages.
baseTeamSchema = z.object({
slug: z.string(),
isFounder: z.boolean().optional().default(false),
givenName: z.string(),
surname: z.string(),
email: z.string().email().optional(),
role: z.string().optional(),
bio: z.string().optional(),
avatar: z.object({
src: z.string(),
alt: z.string(),
}),
links: z.array(z.object({
label: z.string(),
url: z.string().url(),
icon: z.string().optional(),
})).optional(),
})
baseFaqSchema
FAQ collections with type-based filtering.
baseFaqSchema = z.object({
type: z.string(),
label: z.string(),
icon: z.string(),
color: z.enum(['error', 'warning', 'success', 'info']),
items: z.array(z.object({
label: z.string(),
content: z.string(),
})),
})
baseReferencesSchema
Academic references and sources with credibility tracking.
baseReferencesSchema = z.object({
category: z.object({
id: z.string(),
label: z.string(),
}),
sources: z.array(z.object({
id: z.string(),
title: z.string(),
author: z.string().optional(),
date: z.string(),
description: z.string().optional(),
credibilityScore: z.number().min(1).max(10).optional(),
affiliation: z.string().optional(),
pdf: z.string().optional(),
url: z.string().optional(),
})),
})
baseGlossarySchema
Glossary terms organized by category.
baseGlossarySchema = z.object({
category: z.object({
id: z.string(),
label: z.string(),
color: z.string().optional(),
}),
terms: z.array(z.object({
id: z.string(),
term: z.string(),
abbreviation: z.string().optional(),
definition: z.string(),
})),
})
Using Schemas in Your App
Import base schemas and use them in your content.config.ts:
import { defineCollection, defineContentConfig } from '@nuxt/content'
import {
basePageSchema,
baseConfigSchema,
baseNavigationSchema,
baseFaqSchema,
baseTeamSchema,
baseChangelogSchema,
baseReferencesSchema,
baseGlossarySchema,
} from '@incubrain/foundry/schemas'
export default defineContentConfig({
collections: {
pages: defineCollection({
type: 'page',
source: { include: 'pages/**/*.md', prefix: '/' },
schema: basePageSchema,
}),
docs: defineCollection({
type: 'page',
source: { include: 'docs/**/*.md', prefix: '/docs' },
schema: basePageSchema,
}),
// Add only the collections you need
},
})
See Content Overview for more details on working with collections.