content-collection — Claude Code skill: use and install
This skill guides Astro content collections with typed schemas and query patterns. Use it for blogs, docs, changelogs, and other structured content.
npx skills add incluud/astro-agent-skills --skill content-collection -a claude-codeWhat content-collection does
The skill covers collection design, schema changes, and validation. It helps decide between build-time and live data, define required fields and references, and configure loaders with glob() or file(). Schemas use astro/zod, with optional image validation through image().
For reads, it uses getCollection(), getEntry(), and getEntries(). Dynamic routes can use entry.id, while rendered content goes through render(entry). After edits, the workflow includes npx astro sync and checking a real entry from each collection. Astro 6 and later require src/content.config.*; src/content/config.* is the old location.
What it helps with
- design typed Astro content collections
- load entries from local folders or data files
- connect entries with
reference() - migrate collections to the current Content Layer API
- validate schemas after collection changes
Example prompts for the agent
- Set up blog and author collections in
src/content.config.tswith typed fields, references, and image validation. - Migrate this project from the legacy Astro content API and update its entry queries.
- Check every collection after the edit, fix schema errors, then run
npx astro sync.
How to install content-collection
1Skills CLI (Vercel)
npx skills add incluud/astro-agent-skills --skill content-collection -a claude-code2Manually: put the files in place
~/.claude/skills/content-collection/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/content-collection/
1Skills CLI (Vercel)
npx skills add incluud/astro-agent-skills --skill content-collection -a codex2Manually: put the files in place
.agents/skills/content-collection/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add incluud/astro-agent-skills --skill content-collection -a cursor2Manually: put the files in place
.cursor/skills/content-collection/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install incluud/astro-agent-skills content-collection2Manually: put the files in place
.github/skills/content-collection/SKILL.md1Skills CLI (Vercel)
npx skills add incluud/astro-agent-skills --skill content-collection -a gemini-cli2Platform CLI
gemini skills install https://github.com/incluud/astro-agent-skills --path skills/content-collectionManually: put the files in place
.devin/skills/content-collection/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add incluud/astro-agent-skills --skill content-collection -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about content-collection
How do I install content-collection in Claude Code?
Run npx skills add incluud/astro-agent-skills --skill content-collection -a claude-code, then check ~/.claude/skills/content-collection/SKILL.md.
What does content-collection do?
It helps create and refactor Astro collections by defining schemas, loading entries, linking records, and querying them with the current content APIs.
Which Astro API changes does it cover?
For Astro 6 and later, use src/content.config.*, entry.id, getEntry(), and render(entry). Each collection needs a loader, while legacy collection types should be removed.
Source text
SKILL.md · MIT
---
name: content-collection
description: Set up and evolve Astro content collections with typed schemas and reliable querying patterns.
---
# Astro Content Collections
Use this skill when creating or refactoring structured content in Astro, such as blogs, docs, changelogs, case studies, team data, or other schema-driven content.
If `astro-best-practices` is available, apply it alongside this skill for naming, accessibility, and performance defaults.
## Workflow
### 1. Decide whether the collection is build-time or live
Most content sites should use build-time collections in `src/content.config.*`. Only reach for live collections in `src/live.config.*` when the data truly needs request-time freshness.
Before coding, decide:
- which collections exist
- which fields are required
- which relationships need references
- whether assets such as images should be validated
Favor a schema that reflects how the site queries content, not just how frontmatter currently looks.
### 2. Define collections in `src/content.config.*`
Use the current Content Layer API. For build-time collections:
- define them in `src/content.config.ts` (or `.js` / `.mjs`)
- give every collection a `loader`
- import `z` from `astro/zod`
- do not use `type: 'content'` or `type: 'data'`
Example:
```ts
import { defineCollection, reference } from 'astro:content'
import { glob } from 'astro/loaders'
import { z } from 'astro/zod'
const blog = defineCollection({
loader: glob({ base: './src/content/blog', pattern: '**/*.{md,mdx}' }),
schema: ({ image }) => z.object({
title: z.string(),
description: z.string(),
publishDate: z.coerce.date(),
updatedDate: z.coerce.date().optional(),
author: reference('authors'),
cover: image().optional(),
tags: z.array(z.string()).default([]),
draft: z.boolean().default(false),
}),
})
const authors = defineCollection({
loader: glob({ base: './src/data/authors', pattern: '**/*.json' }),
schema: z.object({
name: z.string(),
email: z.email().optional(),
avatar: z.url().optional(),
}),
})
export const collections = { blog, authors }
```
Useful patterns:
- `glob()` for folders of local entries
- `file()` for a single JSON or other data file
- `z.enum(...)` for controlled values
- `z.coerce.date()` for frontmatter dates
- `reference('collection-name')` for relationships
- `schema: ({ image }) => ...` when image validation matters
### 3. Keep the collection shape current
For Astro 6 and newer:
- use `src/content.config.*`, not `src/content/config.*`
- use `entry.id` as the slug-like identifier in URLs and queries
- use `entry.filePath` only when you truly need the source path
- use `getEntry()` instead of legacy `getEntryBySlug()` or `getDataEntryById()`
Prefer a stable folder structure and predictable IDs. Avoid scattering content across route folders if it is logically a collection.
### 4. Query with intent
Use the content APIs that match the job:
- `getCollection()` for lists
- `getEntry()` for a single known entry
- `getEntries()` for arrays of references
- collection filters for draft/published splits
Example:
```astro
---
import { getCollection } from 'astro:content'
const posts = await getCollection('blog', ({ data }) => !data.draft)
---
```
When rendering entries, keep route generation and content rendering separate enough that each part remains easy to reason about.
### 5. Wire routes and rendering with the current API
For dynamic routes:
- build paths from collection IDs
- pass the entry through props cleanly
- render content with `render(entry)`
Example:
```astro
---
import { getCollection, render } from 'astro:content'
export async function getStaticPaths() {
const posts = await getCollection('blog')
return posts.map((post) => ({
params: { slug: post.id },
props: { post },
}))
}
const { post } = Astro.props
const { Content } = await render(post)
---
<article>
<h1>{post.data.title}</h1>
<Content />
</article>
```
### 6. Sync and validate
After changing collections:
- run `npx astro sync` or the repo’s normal Astro workflow
- fix schema mismatches instead of weakening types
- validate at least one real entry per collection
- watch for warnings about missing loaders, legacy config paths, or deprecated imports
## Migration Guidance
When migrating from older content patterns:
1. move `src/content/config.ts` to `src/content.config.ts`
2. add a `loader` to every collection
3. remove any `type: 'content'` or `type: 'data'`
4. replace `import { defineCollection, z } from 'astro:content'` with `import { defineCollection } from 'astro:content'` and `import { z } from 'astro/zod'`
5. replace `post.slug` with `post.id`
6. replace `entry.render()` with `render(entry)`
7. replace `getEntryBySlug()` and `getDataEntryById()` with `getEntry()`
If the project is crossing Astro versions at the same time, verify version-sensitive content APIs in the current official Astro docs before finalizing.
© incluud · MIT · incluud/astro-agent-skills