Nuxt Content v3 Git-based CMS for Markdown/MDC content sites. Use for blogs, docs, content-driven apps with type-safe queries, schema validation (Zod/Valibot), full-text search, navigation utilities. Supports Nuxt Studio production editing, Cloudflare D1/Pages deployment, Vercel deployment, SQL storage, MDC components, content collections.
npx skills add https://github.com/secondsky/claude-skills --skill nuxt-content
Status: Production Ready
Last Updated: 2025-01-10
Dependencies: None
Latest Versions: @nuxt/content@^3.0.0, nuxt-studio@^0.1.0-alpha, zod@^4.1.12, valibot@^0.42.0, better-sqlite3@^11.0.0
Nuxt Content v3 is a powerful Git-based CMS for Nuxt projects that manages content through Markdown, YAML, JSON, and CSV files. It transforms content files into structured data with type-safe queries, automatic validation, and SQL-based storage for optimal performance.
Major Improvements:
Use this skill when:
# Bun (recommended)
bun add @nuxt/content better-sqlite3
# npm
npm install @nuxt/content better-sqlite3
# pnpm
pnpm add @nuxt/content better-sqlite3
Why this matters:
@nuxt/content is the core CMS modulebetter-sqlite3 provides SQL storage for optimal performance// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/content']
})
CRITICAL:
modules array (not buildModules)// content.config.ts
import { defineContentConfig, defineCollection } from '@nuxt/content'
import { z } from 'zod'
export default defineContentConfig({
collections: {
content: defineCollection({
type: 'page',
source: '**/*.md',
schema: z.object({
tags: z.array(z.string()).optional(),
date: z.date().optional()
})
})
}
})
Create content file:
<!-- content/index.md -->
---
title: Hello World
description: My first Nuxt Content page
tags: ['nuxt', 'content']
---
# Welcome to Nuxt Content v3
This is my first content-driven site!
<!-- pages/[...slug].vue -->
<script setup>
const route = useRoute()
const { data: page } = await useAsyncData(route.path, () =>
queryCollection('content').path(route.path).first()
)
</script>
<template>
<ContentRenderer v-if="page" :value="page" />
</template>
See Full Template: templates/blog-collection-setup.ts
content.config.ts before querying2024-01-15 or 2024-01-15T10:30:00Zcontent.config.ts.only() to select specific fields (performance)components/content/ directory01-, 02-better-sqlite3 required<!--more--> in content to separate excerpts10. D1 Binding Must Be "DB" (case-sensitive) on Cloudflare
content.config.ts.only())components/content/01- not 1-)<!--more--> divider10. Don't Use Different Binding Names for D1 (must be "DB")
Collections organize related content with shared configuration:
// content.config.ts
import { defineCollection, defineContentConfig } from '@nuxt/content'
import { z } from 'zod'
export default defineContentConfig({
collections: {
blog: defineCollection({
type: 'page',
source: 'blog/**/*.md',
schema: z.object({
title: z.string(),
date: z.date(),
tags: z.array(z.string()).default([])
})
}),
authors: defineCollection({
type: 'data',
source: 'authors/*.yml',
schema: z.object({
name: z.string(),
bio: z.string()
})
})
}
})
type: 'page')Use for: Content that maps to URLs
Features:
path, title, description, body, navigationPath Mapping:
content/index.md → /
content/about.md → /about
content/blog/hello.md → /blog/hello
type: 'data')Use for: Structured data without URLs
Features:
bun add -D zod@^4.1.12
# or: npm install -D zod@^4.1.12
import { z } from 'zod'
schema: z.object({
title: z.string(),
date: z.date(),
published: z.boolean().default(false),
tags: z.array(z.string()).optional(),
category: z.enum(['news', 'tutorial', 'update'])
})
bun add -D valibot@^0.42.0
# or: npm install -D valibot@^0.42.0
import * as v from 'valibot'
schema: v.object({
title: v.string(),
date: v.date(),
published: v.boolean(false),
tags: v.optional(v.array(v.string()))
})
// Get all posts
const posts = await queryCollection('blog').all()
// Get single post by path
const post = await queryCollection('blog').path('/blog/hello').first()
// Get post by ID
const post = await queryCollection('blog').where('_id', '=', 'hello').first()
// Select specific fields (performance optimization)
const posts = await queryCollection('blog')
.only(['title', 'description', 'date', 'path'])
.all()
// Exclude fields
const posts = await queryCollection('blog')
.without(['body'])
.all()
// Single condition
const posts = await queryCollection('blog')
.where('published', '=', true)
.all()
// Multiple conditions
const posts = await queryCollection('blog')
.where('published', '=', true)
.where('category', '=', 'tutorial')
.all()
// Operators: =, !=, <, <=, >, >=, in, not-in, like
const recent = await queryCollection('blog')
.where('date', '>', new Date('2024-01-01'))
.all()
const tagged = await queryCollection('blog')
.where('tags', 'in', ['nuxt', 'vue'])
.all()
// Sort by field
const posts = await queryCollection('blog')
.sort('date', 'DESC')
.all()
// Pagination
const posts = await queryCollection('blog')
.sort('date', 'DESC')
.limit(10)
.offset(0)
.all()
// Count results
const total = await queryCollection('blog')
.where('published', '=', true)
.count()
// server/api/posts.get.ts
export default defineEventHandler(async (event) => {
const posts = await queryCollection('blog')
.where('published', '=', true)
.sort('date', 'DESC')
.all()
return { posts }
})
Auto-generate navigation tree from content structure:
const navigation = await queryCollectionNavigation('blog').all()
Returns hierarchical structure:
[
{
title: 'Getting Started',
path: '/docs/getting-started',
children: [{ title: 'Installation', path: '/docs/getting-started/installation' }]
}
]
Advanced patterns (filters, ordering, custom structures): See references/collection-examples.md
<!-- Default slot -->
::my-alert
This is an alert message
::
<!-- Named slots -->
::my-card
#title
Card Title
#default
Card content here
::
Component:
<!-- components/content/MyAlert.vue -->
<template>
<div class="alert">
<slot />
</div>
</template>
::my-button{href="/docs" type="primary"}
Click me
::
Component:
<!-- components/content/MyButton.vue -->
<script setup>
defineProps<{
href: string
type: 'primary' | 'secondary'
}>()
</script>
// Search across all content
const results = await queryCollectionSearchSections('blog', 'nuxt content')
.where('published', '=', true)
.all()
Returns:
[
{
id: 'hello',
path: '/blog/hello',
title: 'Hello World',
content: '...matching text...'
}
]
bun add -D @nuxthub/core
bunx wrangler d1 create nuxt-content
bun run build && bunx wrangler pages deploy dist
wrangler.toml:
[[d1_databases]]
binding = "DB" # Must be exactly "DB" (case-sensitive)
database_name = "nuxt-content"
database_id = "your-database-id"
CRITICAL: D1 binding MUST be named DB (case-sensitive).
See: references/deployment-checklists.md for complete Cloudflare deployment guide with troubleshooting.
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/content'],
routeRules: {
'/blog/**': { prerender: true }
}
})
vercel deploy
See: references/deployment-checklists.md for complete Vercel configuration and prerender strategy.
bun add -D nuxt-studio@alpha
# or: npm install -D nuxt-studio@alpha
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/content', 'nuxt-studio'],
studio: {
enabled: true,
gitInfo: {
name: 'your-name',
email: '[email protected]'
}
}
})
https://yourdomain.com/api/__studio/oauth/callbackCRITICAL: Callback URL must match production domain exactly (including https://).
Error: Collection 'xyz' not found
Solution: Define collection in content.config.ts and restart dev server
rm -rf .nuxt && bun dev
Error: Validation error: Expected date, received string
Solution: Use ISO 8601 format:
---
date: 2024-01-15 # ✅ Correct
# NOT: "January 15, 2024" # ❌ Wrong
---
Error: DB is not defined
Solution: D1 binding name must be exactly DB (case-sensitive) in Cloudflare dashboard.
Error: Components show as raw text
Solution: Place components in components/content/ with exact name matching:
<!-- components/content/MyAlert.vue -->
::my-alert
Content
::
Error: New content doesn't appear in navigation
Solution: Clear .nuxt cache:
rm -rf .nuxt && bun dev
See All 18 Issues: references/error-catalog.md
Load references/error-catalog.md when:
Load references/collection-examples.md when:
Load references/query-operators.md when:
Load references/deployment-checklists.md when:
Load references/mdc-syntax-reference.md when:
Load references/studio-setup-guide.md when:
Templates (templates/):
blog-collection-setup.ts - Complete blog setup with collections, queries, navigation, search, and deployment (334 lines).only() to select specific fieldscomponents/content/<!--more--> for excerpts.nuxt after config changes10. Use pagination for large datasets
This skill composes well with:
When installing CMS packages, follow supply chain security best practices:
npm config set ignore-scripts true (or Bun: disabled by default)socket package score npm <pkg> or use socket npm install <pkg> to check packagesLoad the dependency-upgrade skill for full security configuration including Socket CLI integration, cooldown setup, lockfile validation, and CI enforcement.
Official Documentation:
Examples:
Production Tested: Documentation sites, blogs, content platforms
Last Updated: 2025-01-27
Token Savings: ~60% (reduces content + error documentation)
Assess Kubernetes workloads and cluster configuration for AKS Automatic compatibility. Identifies incompatibilities, generates fixes, and guides migration from AKS Standard to AKS Automatic. WHEN: migrate to AKS Automatic, check AKS Automatic readiness, validate manifests for Automatic, assess cluster for Automatic compatibility, fix deployment for Automatic compatibility, identify AKS Automatic migration blockers, is my cluster ready for AKS Automatic.
Discovers available Azure OpenAI model capacity across regions and projects. Analyzes quota limits, compares availability, and recommends optimal deployment locations based on capacity requirements. USE FOR: find capacity, check quota, where can I deploy, capacity discovery, best region for capacity, multi-project capacity search, quota analysis, model availability, region comparison, check TPM availability. DO NOT USE FOR: actual deployment (hand off to preset or customize after discovery), quota increase requests (direct user to Azure Portal), listing existing deployments.
Interactive guided deployment flow for Azure OpenAI models with full customization control. Step-by-step selection of model version, SKU (GlobalStandard/Standard/ProvisionedManaged), capacity, RAI policy (content filter), and advanced options (dynamic quota, priority processing, spillover). USE FOR: custom deployment, customize model deployment, choose version, select SKU, set capacity, configure content filter, RAI policy, deployment options, detailed deployment, advanced deployment, PTU deployment, provisioned throughput. DO NOT USE FOR: quick deployment to optimal region (use preset).
Unified Azure OpenAI model deployment skill with intelligent intent-based routing. Handles quick preset deployments, fully customized deployments (version/SKU/capacity/RAI policy), and capacity discovery across regions and projects. USE FOR: deploy model, deploy gpt, create deployment, model deployment, deploy openai model, set up model, provision model, find capacity, check model availability, where can I deploy, best region for model, capacity analysis. DO NOT USE FOR: listing existing deployments (use foundry_models_deployments_list MCP tool), deleting deployments, agent creation (use agent/create), project creation (use project/create).
Intelligently deploys Azure OpenAI models to optimal regions by analyzing capacity across all available regions. Automatically checks current region first and shows alternatives if needed. USE FOR: quick deployment, optimal region, best region, automatic region selection, fast setup, multi-region capacity check, high availability deployment, deploy to best location. DO NOT USE FOR: custom SKU selection (use customize), specific version selection (use customize), custom capacity configuration (use customize), PTU deployments (use customize).
This skill should be used when working with LaminDB, an open-source data framework for biology that makes data queryable, traceable, reproducible, and FAIR. Use when managing biological datasets (scRNA-seq, spatial, flow cytometry, etc.), tracking computational workflows, curating and validating data with biological ontologies, building data lakehouses, or ensuring data lineage and reproducibility in biological research. Covers data management, annotation, ontologies (genes, cell types, diseases, tissues), schema validation, integrations with workflow managers (Nextflow, Snakemake) and MLOps platforms (W&B, MLflow), and deployment strategies.
Latch platform for bioinformatics workflows. Build pipelines with Latch SDK, @workflow/@task decorators, deploy serverless workflows, LatchFile/LatchDir, Nextflow/Snakemake integration.
Run Python code in the cloud with serverless containers, GPUs, and autoscaling. Use when deploying ML models, running batch processing jobs, scheduling compute-intensive tasks, or serving APIs that require GPU acceleration or dynamic scaling.
Take secondsky/nuxt-content from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference npm, pnpm.
Without those the skill loads but fails at the first command.