CursorPool
← 返回首页

Astro

Cursor plugin for Astro containing tools to assist you during development including the official Astro Docs MCP, rules with best practises and coding standards and several skills such as add integration, content collection, create component, docs lookup and migrate.

cursor.directory·60
规则

Astro framework best practices for performant, accessible, and maintainable projects

Astro framework best practices for performant, accessible, and maintainable projects

# Astro Best Practices

## Core Principles

- Prefer static generation (SSG) over server-side rendering when possible
- Use partial hydration with `client:*` directives only when JavaScript is required
- Keep client-side JavaScript minimal for optimal performance
- Follow Astro's file-based routing conventions

## Project Structure

```
src/content.config.ts  # Build-time content collection definitions
src/
├── components/    # Reusable UI components (.astro, .tsx, .vue)
├── layouts/       # Page layouts with common structure
├── pages/         # File-based routes
├── content/       # Content entries (Markdown/MDX)
├── styles/        # Global styles
└── assets/        # Processed assets (images, fonts)
public/            # Static assets (served as-is)
```

## Components

- Use `.astro` components for static content (zero JS by default)
- Reserve framework components (React, Vue, Svelte) for interactive features
- Apply client directives strategically:
  - `client:load` - Critical interactivity needed immediately
  - `client:idle` - Lower priority, load when browser is idle
  - `client:visible` - Load when component enters viewport
  - `client:media` - Load based on media query
  - `client:only` - Skip server render entirely

## Content Collections

- Define collections in `src/content.config.ts`
- Use loaders and Zod schemas for type-safe content
- Use `getCollection()` and `getEntry()` for querying
- Use `render(entry)` instead of relying on legacy `entry.render()`
- Leverage frontmatter for metadata
- Prefer MDX for content requiring components

## Performance

- Use `<Image />` component for automatic optimization
- Implement view transitions and client routing with `<ClientRouter />` when appropriate
- Minimize layout shifts with proper image dimensions
- Use content collections for large content sites

## Accessibility

- Use semantic HTML elements (`<nav>`, `<main>`, `<article>`, etc.)
- Ensure keyboard navigation works for all interactive elements
- Provide alt text for images (or `alt=""` for decorative images)
- Maintain proper heading hierarchy (h1 → h6)
- Test with screen readers and keyboard-only navigation

## Data Fetching

- Fetch data in component frontmatter (server-side by default)
- Use `Astro.props` for component data passing
- Implement `getStaticPaths()` for dynamic routes in SSG mode
- Consider API routes for server-side endpoints

## Styling

- Scoped styles are default in `.astro` components
- Use `is:global` directive sparingly for global styles
- Prefer CSS custom properties for theming
- Support dark mode with `prefers-color-scheme` or class-based toggle

## Common Patterns

```astro
---
// Frontmatter: runs at build time (SSG) or request time (SSR)
import Layout from '../layouts/Layout.astro'
import { getCollection } from 'astro:content'

const posts = await getCollection('blog')
---

<Layout title="Blog">
  <main>
    {posts.map(post => (
      <article>
        <h2>{post.data.title}</h2>
      </article>
    ))}
  </main>
</Layout>

<style>
  /* Scoped by default */
  article {
    padding: 1rem;
  }
</style>
```
MCP

Astro Docs

MCP server: Astro Docs

{
  "url": "https://mcp.docs.astro.build/mcp"
}
Skill

add-integration

Guide complete integration setup including post-install configuration. Use when adding UI frameworks, adapters, or tooling to an Astro project.

# Add Integration

## When to Use

- Adding a UI framework (React, Vue, Svelte, etc.)
- Setting up Tailwind CSS or other styling tools
- Configuring deployment adapters (Netlify, Vercel, Cloudflare)
- Installing community integrations
- Troubleshooting integration issues

## Instructions

### 1. Identify Integration Type

| Type | Examples | Key Considerations |
|------|----------|-------------------|
| **UI Framework** | React, Vue, Svelte, Solid, Preact | Client directives, hydration strategy |
| **Styling** | Tailwind, UnoCSS | CSS setup, config files |
| **Adapter** | Netlify, Vercel, Node, Cloudflare | Output mode, environment variables |
| **Content** | MDX, Markdoc | Content collections integration |
| **Other** | Sitemap, Partytown, DB | Feature-specific config |

### 2. Installation

**Official integrations** (support `astro add`):

```bash
npx astro add react
npx astro add tailwind
npx astro add netlify
```

**Community integrations** (manual install):

```bash
npm install astro-integration-name
```

Then add to `astro.config.mjs`:

```javascript
import { defineConfig } from 'astro/config'
import integration from 'astro-integration-name'

export default defineConfig({
  integrations: [integration()],
})
```

#### Astro 6 upgrade note

If the project is upgrading Astro itself, do not upgrade integrations in isolation:

1. Verify the environment is running Node 22.12.0 or newer
2. Upgrade Astro and official integrations/adapters together
3. Re-check the official docs before copying older config snippets into the project

This catches a large class of "the integration broke" issues that are actually runtime or version skew problems.

### 3. Post-Install Configuration

#### Tailwind CSS v4

After `npx astro add tailwind`:

1. Create CSS file `src/styles/global.css`:
   ```css
   @import "tailwindcss";
   ```

2. Import in your layout:
   ```astro
   ---
   import '../styles/global.css'
   ---
   ```

3. Optional: Configure in `tailwind.config.mjs` for customization

#### React / Vue / Svelte

After adding a framework, understand client directives:

```astro
---
import Counter from './Counter.tsx'
---

<!-- No directive = server-rendered only, no JS -->
<Counter />

<!-- client:load = hydrate immediately (critical interactivity) -->
<Counter client:load />

<!-- client:idle = hydrate when browser is idle -->
<Counter client:idle />

<!-- client:visible = hydrate when scrolled into view -->
<Counter client:visible />

<!-- client:media = hydrate on media query match -->
<Counter client:media="(max-width: 768px)" />

<!-- client:only = skip server render entirely -->
<Counter client:only="react" />
```

**Best practice**: Start with `client:visible` or `client:idle`, use `client:load` only for above-the-fold critical UI.

#### Deployment Adapters

**Netlify** (`npx astro add netlify`):

```javascript
// astro.config.mjs
import { defineConfig } from 'astro/config'
import netlify from '@astrojs/netlify'

export default defineConfig({
  output: 'server', // or 'hybrid'
  adapter: netlify(),
})
```

Set environment variables in Netlify dashboard or `netlify.toml`.

**Vercel** (`npx astro add vercel`):

```javascript
import { defineConfig } from 'astro/config'
import vercel from '@astrojs/vercel'

export default defineConfig({
  output: 'server',
  adapter: vercel({
    webAnalytics: { enabled: true }, // Optional
  }),
})
```

**Cloudflare** (`npx astro add cloudflare`):

```javascript
import { defineConfig } from 'astro/config'
import cloudflare from '@astrojs/cloudflare'

export default defineConfig({
  output: 'server',
  adapter: cloudflare({
    platformProxy: { enabled: true }, // For local dev
  }),
})
```

#### MDX

After `npx astro add mdx`:

- `.mdx` files work in `src/pages/` and `src/content/`
- Import components directly in MDX files
- Configure remark/rehype plugins in `astro.config.mjs`:

```javascript
import { defineConfig } from 'astro/config'
import mdx from '@astrojs/mdx'

export default defineConfig({
  integrations: [mdx()],
  markdown: {
    remarkPlugins: [remarkPlugin],
    rehypePlugins: [rehypePlugin],
  },
})
```

### 4. Multiple Integrations

Order can matter. General guidelines:

```javascript
export default defineConfig({
  integrations: [
    // UI frameworks first
    react(),
    vue(),
    // Then styling
    tailwind(),
    // Then content
    mdx(),
    // Then utilities
    sitemap(),
  ],
})
```

### 5. Troubleshooting

| Issue | Solution |
|-------|----------|
| "Cannot find module" | Run `npm install` again, check package.json |
| Styles not loading | Check CSS import path, restart dev server |
| Hydration mismatch | Ensure server/client render same content |
| Build fails | Check adapter matches deployment platform |
| Build fails after Astro upgrade | Verify Node version, then upgrade official integrations/adapters alongside Astro |
| Integration not working | Verify it's in `integrations[]` array |

## Finding Integrations

- **Official**: [docs.astro.build/integrations](https://docs.astro.build/en/guides/integrations-guide/)
- **Community**: [astro.build/integrations](https://astro.build/integrations/)
Skill

content-collection

Set up and configure Astro content collections with the current Content Layer API and type-safe schemas. Use when creating blogs, docs, or any structured content.

# Content Collection Setup

## When to Use

- Setting up a new blog, documentation, or portfolio
- Creating structured content with frontmatter validation
- Migrating from `Astro.glob()` or legacy content collections
- Adding new collection types to an existing project

## Instructions

### 1. Understand the Structure

In Astro 6+, build-time content collections are configured in `src/content.config.ts`, while the content entries themselves can live in `src/content/` or another folder you point to with a loader.

Typical structure:

```text
src/
├── content.config.ts      # Collection definitions
├── content/
│   └── blog/
│       ├── post-1.md
│       ├── post-2.mdx
│       └── drafts/
│           └── draft.md
└── data/
    └── authors.json       # Single-file data collection example
```

If you need request-time fresh data, use live collections in `src/live.config.ts`. For most blogs, docs, and portfolios, build-time collections are the right default.

### 2. Define the Schema

Create `src/content.config.ts` (or `.js` / `.mjs`):

```typescript
import { defineCollection, reference } from 'astro:content'
import { glob, file } 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: file('src/data/authors.json'),
  schema: z.object({
    id: z.string(),
    name: z.string(),
    email: z.string().email().optional(),
    avatar: z.string().url().optional(),
  }),
})

export const collections = { blog, authors }
```

Notes:

- Every collection needs a `loader`
- Import `z` from `astro/zod`, not from `astro:content`
- Do not use `type: 'content'` or `type: 'data'` in Astro 6+
- When using `file()`, each entry needs a unique `id`

### 3. Common Schema Patterns

#### Images with validation

```typescript
import { defineCollection } 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(),
    cover: image(), // Validates the file exists
    coverAlt: z.string(),
  }),
})
```

#### Reference other collections

```typescript
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: z.object({
    title: z.string(),
    author: reference('authors'), // References an authors entry by id
    relatedPosts: z.array(reference('blog')).optional(),
  }),
})
```

#### Enum for categories

```typescript
schema: z.object({
  category: z.enum(['tutorial', 'guide', 'reference', 'blog']),
  status: z.enum(['draft', 'review', 'published']).default('draft'),
})
```

If you store data entries as separate JSON files instead of one JSON file, use `glob({ base: './src/data/authors', pattern: '**/*.json' })` instead of `file()`.

### 4. Query Collections

```astro
---
import { getCollection, getEntry, render } from 'astro:content'

// Get all entries
const allPosts = await getCollection('blog')

// Filter entries
const publishedPosts = await getCollection('blog', ({ data }) => {
  return data.draft !== true
})

// Get single entry by id
const post = await getEntry('blog', 'my-post')

// Render content
const { Content, headings } = await render(post)
---

<Content />
```

Important changes in Astro 6+:

- Use `entry.id` as the slug-like identifier
- Use `render(entry)` instead of `entry.render()`
- Use `getEntry()` instead of older slug-specific helpers

### 5. Dynamic Routes

Create `src/pages/blog/[...slug].astro`:

```astro
---
import { getCollection, render } from 'astro:content'
import BlogLayout from '../../layouts/BlogLayout.astro'

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)
---

<BlogLayout title={post.data.title}>
  <article>
    <h1>{post.data.title}</h1>
    <time datetime={post.data.publishDate.toISOString()}>
      {post.data.publishDate.toLocaleDateString()}
    </time>
    <Content />
  </article>
</BlogLayout>
```

If you need the original file location for debugging or special routing logic, use `post.filePath`. For URLs and lookups, use `post.id`.

### 6. Generate Types

Run `astro sync` or `astro dev` to generate TypeScript types:

```bash
npx astro sync
```

This creates `.astro/` with type definitions for your collections.

## Migration from Astro.glob() and Legacy Content Collections

If migrating from the old `Astro.glob()` or pre-Content Layer pattern:

1. Move `src/content/config.ts` to `src/content.config.ts`
2. Add a `loader` to every collection
3. Remove `type: 'content'` and `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 `post.render()` with `render(post)`
7. Replace `Astro.glob()` with `getCollection()` or `import.meta.glob()`

## Troubleshooting

| Issue | Solution |
|-------|----------|
| `LegacyContentConfigError` | Move `src/content/config.ts` to `src/content.config.ts` |
| `ContentCollectionMissingALoaderError` | Add a `loader` to the collection definition |
| `ContentCollectionInvalidTypeError` | Remove `type: 'content'` or `type: 'data'` |
| Content entry not found by slug | Use `entry.id` instead of `entry.slug` |
| Render method missing | Import `render` from `astro:content` and call `render(entry)` |
| Images not validating | Use `schema: ({ image }) =>` function syntax |
Skill

create-component

Scaffold Astro components, pages, and layouts with best practices. Use when creating new .astro files or converting designs to components.

# Create Astro Component

## When to Use

- Creating new `.astro` components, pages, or layouts
- Scaffolding from a design or description
- Converting static HTML to Astro components
- Setting up new content collection entries

## Instructions

### 1. Determine Component Type

Ask or infer what type of file is needed:

| Type | Location | Purpose |
|------|----------|---------|
| **Component** | `src/components/` | Reusable UI element |
| **Page** | `src/pages/` | Route endpoint |
| **Layout** | `src/layouts/` | Page wrapper with common structure |
| **Content** | `src/content/` | Markdown/MDX content entry |

### 2. Gather Requirements

Before scaffolding, clarify:
- What props does it need?
- Is client-side JavaScript required?
- Does it need to fetch data?
- What styling approach (scoped, Tailwind, global)?

### 3. Scaffold with Best Practices

#### Component Template

```astro
---
interface Props {
  title: string
  variant?: 'primary' | 'secondary'
}

const { title, variant = 'primary' } = Astro.props
---

<div class:list={['component', variant]}>
  <h2>{title}</h2>
  <slot />
</div>

<style>
  .component {
    /* Scoped styles */
  }
</style>
```

#### Page Template

```astro
---
import Layout from '../layouts/Layout.astro'

const pageTitle = 'Page Title'
---

<Layout title={pageTitle}>
  <main>
    <h1>{pageTitle}</h1>
    <slot />
  </main>
</Layout>
```

#### Layout Template

```astro
---
interface Props {
  title: string
  description?: string
}

const { title, description } = Astro.props
---

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content={description} />
    <title>{title}</title>
  </head>
  <body>
    <slot />
  </body>
</html>
```

### 4. Apply Conventions

- **Naming**: PascalCase for components (`Button.astro`, `NavBar.astro`)
- **Props**: Use TypeScript interface for type safety
- **Defaults**: Provide sensible defaults for optional props
- **Slots**: Use named slots for complex layouts
- **Styles**: Prefer scoped styles, use `class:list` for conditional classes

### 5. Accessibility Checklist

Before finalizing, verify:
- [ ] Semantic HTML elements used appropriately
- [ ] Interactive elements are keyboard accessible
- [ ] Images have alt text (or `alt=""` if decorative)
- [ ] Heading hierarchy is logical
- [ ] Color contrast meets WCAG AA (4.5:1 for text)
- [ ] Focus indicators are visible

## Dynamic Routes

For pages with dynamic routes:

```astro
---
// src/pages/blog/[slug].astro
import { getCollection } from 'astro:content'

export async function getStaticPaths() {
  const posts = await getCollection('blog')
  return posts.map(post => ({
    params: { slug: post.slug },
    props: { post }
  }))
}

const { post } = Astro.props
const { Content } = await post.render()
---

<Layout title={post.data.title}>
  <article>
    <h1>{post.data.title}</h1>
    <Content />
  </article>
</Layout>
```

## Interactive Components

When client-side JS is needed:

```astro
---
import Counter from '../components/Counter.tsx'
---

<!-- Only hydrate when visible in viewport -->
<Counter client:visible initialCount={0} />
```

Choose the appropriate client directive based on priority and use case.
Skill

docs-lookup

Search and retrieve Astro documentation using the Astro Docs MCP. Use when answering questions about Astro APIs, configuration, integrations, or best practices.

# Astro Documentation Lookup

## When to Use

- User asks about Astro features, APIs, or configuration
- Need to verify correct syntax or usage patterns
- Looking up integration setup (Tailwind, MDX, adapters, etc.)
- Checking deployment or adapter documentation
- Answering "how do I..." questions about Astro

## Instructions

1. **Identify the topic** from the user's question (e.g., "content collections", "view transitions", "SSR adapters")

2. **Search the documentation** using the Astro Docs MCP:
   ```
   Use the search_astro_docs tool with relevant keywords
   ```

3. **Review results** and select the most relevant documentation sections

4. **Synthesize the answer** by:
   - Providing a concise explanation
   - Including relevant code examples from the docs
   - Linking to the full documentation when helpful

5. **Verify accuracy** - If the MCP returns no results, try:
   - Alternative search terms
   - Breaking down complex queries
   - Searching for related concepts

## Search Tips

- Use specific terms: "content collections schema" vs just "collections"
- Include version-specific terms if relevant: "Astro 6 content layer" or "upgrade to v6"
- Search for error messages directly when debugging
- Look for integration names: "astro tailwind integration"
- For major upgrades, search the upgrade guide before relying on feature pages alone

## Example Queries

| User Question | Search Terms |
|--------------|--------------|
| "How do I add Tailwind?" | `tailwind integration setup` |
| "What are content collections?" | `content collections` |
| "How do I deploy to Vercel?" | `vercel adapter deployment` |
| "View transitions not working" | `view transitions troubleshooting` |
| "How do I migrate content collections to Astro 6?" | `upgrade to v6 content collections` |

## Response Format

When answering documentation questions:

1. **Brief answer** - One or two sentences summarizing the solution
2. **Code example** - Working snippet demonstrating the concept
3. **Key details** - Important caveats or options to consider
4. **Further reading** - Link to relevant docs section if complex topic
Skill

migrate

Guide migration to Astro from other frameworks or between Astro versions. Use when converting Next.js, Nuxt, Gatsby projects or upgrading Astro.

# Migrate to Astro

## When to Use

- Migrating from Next.js, Nuxt, Gatsby, or other frameworks
- Upgrading between major Astro versions
- Converting a static HTML site to Astro
- Moving from Create React App to Astro

## Instructions

### 1. Identify Migration Path

| From | Complexity | Key Changes |
|------|------------|-------------|
| **Static HTML** | Low | Wrap in `.astro`, add layouts |
| **Next.js (Pages)** | Medium | Route structure similar, convert JSX |
| **Next.js (App)** | Medium-High | Server components map well to Astro |
| **Nuxt** | Medium | Vue components work with integration |
| **Gatsby** | Medium | GraphQL → Content Collections |
| **Create React App** | Medium | Add routing, convert to islands |
| **Astro v4 → v5** | Low-Medium | Content Layer changes begin |
| **Astro v5 → v6** | Medium | Content collections, `Astro.glob()`, and runtime changes |

### 2. Project Setup

Create new Astro project alongside existing:

```bash
npm create astro@latest my-astro-site
```

Or convert in-place by installing Astro:

```bash
npm install astro
```

Update `package.json` scripts:

```json
{
  "scripts": {
    "dev": "astro dev",
    "build": "astro build",
    "preview": "astro preview"
  }
}
```

If upgrading to Astro 6, verify the runtime first:

```bash
node --version
```

Astro 6 requires Node 22.12.0 or newer. Also upgrade official integrations and adapters alongside Astro to avoid version skew.

### 3. Migration Patterns

#### Static HTML → Astro

1. Rename `.html` to `.astro`
2. Move to `src/pages/`
3. Extract repeated sections to `src/layouts/`
4. Convert to components as needed

```astro
---
// src/layouts/Layout.astro
const { title } = Astro.props
---
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>{title}</title>
  </head>
  <body>
    <slot />
  </body>
</html>
```

#### Next.js → Astro

**Pages Router:**

| Next.js | Astro |
|---------|-------|
| `pages/index.js` | `src/pages/index.astro` |
| `pages/blog/[slug].js` | `src/pages/blog/[slug].astro` |
| `getStaticProps` | Frontmatter code block |
| `getStaticPaths` | `getStaticPaths()` export |
| `_app.js` | `src/layouts/Layout.astro` |
| `next/image` | `astro:assets` Image component |
| `next/link` | Standard `<a>` tags |

**Convert a Next.js page:**

```jsx
// Next.js: pages/blog/[slug].js
export async function getStaticPaths() {
  const posts = await getPosts()
  return { paths: posts.map(p => ({ params: { slug: p.slug } })) }
}

export async function getStaticProps({ params }) {
  const post = await getPost(params.slug)
  return { props: { post } }
}

export default function Post({ post }) {
  return <article><h1>{post.title}</h1></article>
}
```

```astro
---
// Astro: src/pages/blog/[slug].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>
```

**Keep React components:**

```bash
npx astro add react
```

Then use with client directives:

```astro
---
import InteractiveWidget from '../components/InteractiveWidget.tsx'
---

<InteractiveWidget client:visible />
```

#### Nuxt → Astro

```bash
npx astro add vue
```

| Nuxt | Astro |
|------|-------|
| `pages/` | `src/pages/` (similar) |
| `components/` | `src/components/` |
| `layouts/` | `src/layouts/` |
| `nuxt.config.ts` | `astro.config.mjs` |
| Auto-imports | Explicit imports |

Vue components work directly:

```astro
---
import MyVueComponent from '../components/MyVueComponent.vue'
---

<MyVueComponent client:load />
```

#### Gatsby → Astro

| Gatsby | Astro |
|--------|-------|
| GraphQL queries | Content Collections |
| `gatsby-image` | `astro:assets` Image |
| `gatsby-plugin-*` | Astro integrations |
| MDX pages | MDX in content collections |

**Convert GraphQL to Content Collections:**

```typescript
// Gatsby: gatsby-node.js with GraphQL
// → Astro: src/content.config.ts with a loader and schema

import { defineCollection } 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: z.object({
    title: z.string(),
    date: z.coerce.date(),
    // Match your Gatsby frontmatter fields
  }),
})

export const collections = { blog }
```

### 4. Astro Version Upgrades

**Upgrade command:**

```bash
npx @astrojs/upgrade
```

**v5 → v6 Key Changes:**

- Node 22.12.0+ is required
- Legacy content collections support is removed
- `src/content/config.ts` moves to `src/content.config.ts`
- Each collection now needs a `loader`
- `z` should come from `astro/zod`
- `entry.id` replaces legacy `slug` usage in collection routing
- `entry.render()` becomes `render(entry)`
- `Astro.glob()` is removed in favor of `import.meta.glob()` or `getCollection()`
- `<ViewTransitions />` is removed; use `<ClientRouter />`
- `Astro.site` inside `getStaticPaths()` should become `import.meta.env.SITE`

**Astro 6 upgrade checklist:**

1. Upgrade Astro and official integrations/adapters together
2. Verify Node 22.12.0+ locally and in CI/deployment
3. Move `src/content/config.ts` to `src/content.config.ts`
4. Add a `loader` to every collection
5. Replace `import { defineCollection, z } from 'astro:content'` with `import { defineCollection } from 'astro:content'` and `import { z } from 'astro/zod'`
6. Replace `post.slug` with `post.id`
7. Replace `post.render()` with `render(post)`
8. Replace `Astro.glob()` with `import.meta.glob()` or `getCollection()`
9. Replace `<ViewTransitions />` with `<ClientRouter />`

Check migration guide: [docs.astro.build/guides/upgrade-to/v6](https://docs.astro.build/en/guides/upgrade-to/v6/)

### 5. Common Migration Tasks

#### Move static assets

```text
public/images/ → public/images/  (same)
src/assets/   → src/assets/      (processed by Vite)
```

#### Update image imports

```astro
---
import { Image } from 'astro:assets'
import heroImage from '../assets/hero.jpg'
---

<Image src={heroImage} alt="Hero" width={800} height={400} />
```

#### Convert CSS

- Global CSS → Import in layout
- CSS Modules → Work as-is
- Styled Components → Use with React integration
- Tailwind → `npx astro add tailwind`

#### Environment variables

```text
// Next.js
NEXT_PUBLIC_API_URL

// Astro
PUBLIC_API_URL  // Client-side
API_SECRET      // Server-side only
```

#### Replace Astro.glob()

```astro
---
// Before
const posts = await Astro.glob('./posts/*.md')

// After
const posts = Object.values(import.meta.glob('./posts/*.md', { eager: true }))
---
```

For content collections, prefer `getCollection()` instead of raw globs.

### 6. Verification Checklist

- [ ] Local and deployment environments meet the required Node version
- [ ] All routes render correctly
- [ ] Content collections build without warnings
- [ ] Images load and are optimized
- [ ] Interactive components hydrate
- [ ] SEO meta tags present
- [ ] Build completes without errors
- [ ] Links work (no 404s)
- [ ] Forms submit correctly
- [ ] Performance improved or maintained

## Resources

- [Official Migration Guides](https://docs.astro.build/en/guides/migrate-to-astro/)
- [Upgrade to Astro v6](https://docs.astro.build/en/guides/upgrade-to/v6/)
- [From Next.js](https://docs.astro.build/en/guides/migrate-to-astro/from-nextjs/)
- [From Nuxt](https://docs.astro.build/en/guides/migrate-to-astro/from-nuxt/)
- [From Gatsby](https://docs.astro.build/en/guides/migrate-to-astro/from-gatsby/)

来源:https://github.com/incluud/astro-cursor-plugin