Claude-skill-registry astro-v6-upgrade
Guide for upgrading Astro projects from v5 to v6. Use when users mention upgrading Astro, Astro v6, Astro 6, or errors related to content collections, ViewTransitions, Astro.glob, Zod schemas, or Content Layer API.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/astro-v6-upgrade" ~/.claude/skills/majiayu000-claude-skill-registry-astro-v6-upgrade && rm -rf "$T"
skills/data/astro-v6-upgrade/SKILL.mdAstro v6 Upgrade Guide
Quick Start
- Check Node version: Astro v6 requires Node 22.12.0+ (
)node -v - Run upgrade:
npx @astrojs/upgrade # npm pnpm dlx @astrojs/upgrade # pnpm - Check for legacy content collections (see below)
- Fix any errors using this guide
Check: Legacy Content Collections
Before upgrading, check if the project needs content collection migration. Most v5 projects already use the Content Layer API and won't need changes.
Decision tree:
-
Does
exist?src/content/config.{js,ts,mjs,mts}- Yes → needs migration (legacy config location)
-
Are there content folders in
but no config file anywhere?src/content/- Yes → needs migration (implicit legacy collections)
-
Otherwise, check
for:src/content.config.{js,ts,mjs,mts}- Any collection without a
property → needs migrationloader - Any collection with
set → needs migrationtype:
- Any collection without a
If any of the above apply, load content-collections.md and follow the migration steps.
Quick Fixes
These are simple renames/replacements. Apply directly:
ViewTransitions → ClientRouter
--- // Before import { ViewTransitions } from 'astro:transitions'; // After import { ClientRouter } from 'astro:transitions'; --- <!-- Before --> <ViewTransitions /> <!-- After --> <ClientRouter />
Remove
handleForms prop if present - it's now default behavior.
Astro.glob() → import.meta.glob()
--- // Before const posts = await Astro.glob('./posts/*.md'); // After const posts = Object.values(import.meta.glob('./posts/*.md', { eager: true })); ---
Zod imports
// Before (deprecated) import { z } from 'astro:content'; import { z } from 'astro:schema'; // After import { z } from 'astro/zod';
If using Zod validation extensively or if you encounter Zod errors, see zod.md for Zod 4 syntax changes.
Deprecated APIs
// Astro.site in getStaticPaths → import.meta.env.SITE export function getStaticPaths() { const site = import.meta.env.SITE; // was Astro.site } // Astro.generator → just remove it // import.meta.env.ASSETS_PREFIX → astro:config/server import { build } from 'astro:config/server'; const prefix = build.assetsPrefix;
Removed: emitESMImage
// Before import { emitESMImage } from 'astro/assets/utils'; // After import { emitImageMetadata } from 'astro/assets/utils';
Error Quick Reference
| Error | Fix |
|---|---|
| Move → |
| Add to collection - see content-collections.md |
| Remove or from collection |
| Replace / with |
| Replace with |
Cannot find | Use (see above) |
Cannot find | Use (see above) |
| Node version error | Upgrade to Node 22.12.0+ |
| Zod validation errors | Check zod.md for Zod 4 changes |
Deep Dive Files
Load these only when needed:
| File | When to load |
|---|---|
| content-collections.md | Legacy content collections need migration |
| zod.md | Using Zod schemas with , , custom errors, or transforms |
| behavior-changes.md | Subtle issues: i18n redirects, script order, env vars, image sizing |
| integration-api.md | Building integrations or adapters |
Experimental Flags to Remove
These flags are now stable or default. Remove from config:
export default defineConfig({ experimental: { // Remove all of these: liveContentCollections: true, preserveScriptOrder: true, staticImportMetaEnv: true, headingIdCompat: true, failOnPrerenderConflict: true, // Use prerenderConflictBehavior instead }, });