diff --git a/.cursor-plugin/marketplace.json b/.cursor-plugin/marketplace.json index 2dc1b24..3a4cc4b 100644 --- a/.cursor-plugin/marketplace.json +++ b/.cursor-plugin/marketplace.json @@ -6,7 +6,7 @@ }, "metadata": { "description": "Professional Cursor plugins with APEX workflow, SOLID principles, and expert development agents for Next.js, Laravel, Swift, Tailwind CSS, and more", - "version": "0.1.1" + "version": "0.1.4" }, "plugins": [ { @@ -58,7 +58,7 @@ "name": "fuse-astro", "source": ".cursor-plugin/plugins/fuse-astro", "description": "Expert Astro 6 with Islands Architecture, Content Layer, Actions, View Transitions, and multi-framework integration", - "version": "1.0.12", + "version": "1.0.13", "author": { "name": "Fusengine", "email": "hello@fusengine.ch" @@ -81,7 +81,7 @@ "name": "fuse-cartographer", "source": ".cursor-plugin/plugins/fuse-cartographer", "description": "Generates indented markdown maps of the plugin ecosystem for agent navigation", - "version": "1.0.11", + "version": "1.0.12", "author": { "name": "Fusengine", "email": "hello@fusengine.ch" @@ -145,7 +145,7 @@ "name": "fuse-design", "source": ".cursor-plugin/plugins/fuse-design", "description": "Design Director for websites, web apps, iOS, and Android. Generates HTML/CSS directly (Gemini Design MCP, Magic/21st.dev, and shadcn MCP are optional). iOS/Android produce tokens + a device-framed mockup + a handoff spec, never SwiftUI/Compose. Design method, design system tokens, motion, UX copy, and a deterministic design-review gate. Anti-AI-Slop, WCAG 2.2.", - "version": "2.2.8", + "version": "2.2.9", "author": { "name": "Fusengine", "email": "hello@fusengine.ch" @@ -181,7 +181,7 @@ "name": "fuse-go", "source": ".cursor-plugin/plugins/fuse-go", "description": "Expert Go 1.26+ — idioms, concurrency, backend services, cargo-grade tooling (golangci-lint v2, govulncheck), with SOLID principles", - "version": "1.0.5", + "version": "1.0.6", "author": { "name": "Fusengine", "email": "hello@fusengine.ch" @@ -207,7 +207,7 @@ "name": "fuse-laravel", "source": ".cursor-plugin/plugins/fuse-laravel", "description": "Expert Laravel 13 + PHP 8.3+ with SOLID principles, first-class PHP Attributes, Laravel AI SDK, JSON:API Resources, native vector search (pgvector), Eloquent, Livewire, queues with routing, and comprehensive documentation", - "version": "1.2.6", + "version": "1.2.7", "author": { "name": "Fusengine", "email": "hello@fusengine.ch" @@ -247,7 +247,7 @@ "name": "fuse-nextjs", "source": ".cursor-plugin/plugins/fuse-nextjs", "description": "Expert Next.js 16 + React 19 with App Router, Server Components, Prisma 7, and Better Auth", - "version": "1.1.22", + "version": "1.1.23", "author": { "name": "Fusengine", "email": "hello@fusengine.ch" @@ -269,7 +269,7 @@ "name": "fuse-php", "source": ".cursor-plugin/plugins/fuse-php", "description": "Expert modern PHP 8.5/8.4 for non-Laravel projects — libraries, standalone Symfony components, Slim, API-first apps, and CLI tools, with PER Coding Style 3.0, PHPStan, and SOLID principles", - "version": "1.0.5", + "version": "1.0.6", "author": { "name": "Fusengine", "email": "hello@fusengine.ch" @@ -322,7 +322,7 @@ "name": "fuse-react", "source": ".cursor-plugin/plugins/fuse-react", "description": "Expert React 19 with hooks, TanStack Router, Zustand, React Hook Form, Testing Library, shadcn/ui, and SOLID principles", - "version": "1.0.19", + "version": "1.0.20", "author": { "name": "Fusengine", "email": "hello@fusengine.ch" @@ -359,7 +359,7 @@ "name": "fuse-rust", "source": ".cursor-plugin/plugins/fuse-rust", "description": "Expert Rust 1.96+ (2024 edition) — ownership, error handling, async/tokio, axum backends, cargo tooling, with SOLID principles", - "version": "1.0.5", + "version": "1.0.6", "author": { "name": "Fusengine", "email": "hello@fusengine.ch" @@ -408,7 +408,7 @@ "name": "fuse-seo", "source": ".cursor-plugin/plugins/fuse-seo", "description": "SEO/GEO 2026 plugin. Local-first, framework-aware, zero third-party APIs. Covers technical SEO, schema markup, E-E-A-T, AI Overviews optimization, local SEO, sitemaps, hreflang, internal linking, content briefs, semantic clustering, and search experience optimization.", - "version": "1.0.10", + "version": "1.0.11", "author": { "name": "Fusengine" }, @@ -438,7 +438,7 @@ "name": "fuse-shadcn-ui", "source": ".cursor-plugin/plugins/fuse-shadcn-ui", "description": "Expert shadcn/ui with Radix UI and Base UI detection, component patterns, registries, theming, and migration", - "version": "1.0.16", + "version": "1.0.17", "author": { "name": "Fusengine", "email": "hello@fusengine.ch" @@ -462,7 +462,7 @@ "name": "fuse-solid", "source": ".cursor-plugin/plugins/fuse-solid", "description": "SOLID principles enforcement with automatic project detection and validation for all languages", - "version": "1.0.17", + "version": "1.0.18", "author": { "name": "Fusengine", "email": "hello@fusengine.ch" @@ -483,7 +483,7 @@ "name": "fuse-swift-apple-expert", "source": ".cursor-plugin/plugins/fuse-swift-apple-expert", "description": "Expert Swift 6.2 + SwiftUI for iOS 26, macOS 26, iPadOS 26, watchOS 26, visionOS 26, tvOS 26 with Liquid Glass, @Observable, actors, SwiftData inheritance", - "version": "1.1.18", + "version": "1.1.19", "author": { "name": "Fusengine", "email": "hello@fusengine.ch" @@ -510,7 +510,7 @@ "name": "fuse-tailwindcss", "source": ".cursor-plugin/plugins/fuse-tailwindcss", "description": "Expert Tailwind CSS v4.1 - CSS-first configuration, @theme, @utility, @variant, Oxide engine 5x faster, OKLCH colors, container queries, 15 specialized skills", - "version": "1.1.9", + "version": "1.1.10", "author": { "name": "Fusengine", "email": "hello@fusengine.ch" @@ -542,7 +542,7 @@ "name": "fuse-tanstack-start", "source": ".cursor-plugin/plugins/fuse-tanstack-start", "description": "Expert TanStack Start (React, RC) full-stack framework with file-based routing, createServerFn server functions, selective SSR, and Nitro deployment", - "version": "1.0.4", + "version": "1.0.5", "author": { "name": "Fusengine", "email": "hello@fusengine.ch" @@ -567,7 +567,7 @@ "name": "fuse-typescript", "source": ".cursor-plugin/plugins/fuse-typescript", "description": "Expert TypeScript 6.0 for pure TS projects — CLI tools, libraries, scripts, and backends on Node 24 LTS or Bun 1.3, with SOLID principles", - "version": "1.0.5", + "version": "1.0.6", "author": { "name": "Fusengine", "email": "hello@fusengine.ch" diff --git a/.cursor-plugin/plugins/fuse-astro/.cursor-plugin/plugin.json b/.cursor-plugin/plugins/fuse-astro/.cursor-plugin/plugin.json index 8feaa07..e986c37 100644 --- a/.cursor-plugin/plugins/fuse-astro/.cursor-plugin/plugin.json +++ b/.cursor-plugin/plugins/fuse-astro/.cursor-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "fuse-astro", - "version": "1.0.12", + "version": "1.0.13", "description": "Expert Astro 6 with Islands Architecture, Content Layer, Actions, View Transitions, and multi-framework integration", "author": { "name": "Fusengine", diff --git a/.cursor-plugin/plugins/fuse-astro/agents/astro-expert.md b/.cursor-plugin/plugins/fuse-astro/agents/astro-expert.md index 18da274..bb88e42 100644 --- a/.cursor-plugin/plugins/fuse-astro/agents/astro-expert.md +++ b/.cursor-plugin/plugins/fuse-astro/agents/astro-expert.md @@ -138,7 +138,7 @@ This agent activates when ANY of the following are detected: ## Content Strategy - **Static sites** — `output: 'static'` + Content Collections for blogs/docs -- **Hybrid sites** — `output: 'hybrid'` with `prerender = false` for dynamic pages +- **Hybrid sites** — `output: 'static'` + adapter, with `prerender = false` for dynamic pages (there is no `output: 'hybrid'`) - **Full SSR** — `output: 'server'` + adapter for apps with auth/session --- diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-7/SKILL.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-7/SKILL.md index b064320..b812af1 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-7/SKILL.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-7/SKILL.md @@ -1,6 +1,6 @@ --- name: astro-7 -description: Use when building Astro 7 sites, choosing an output mode (static/server/hybrid), configuring middleware, or upgrading from Astro 5/6. +description: Use when building Astro 7 sites, choosing an output mode (static/server, hybrid via per-route prerender), configuring middleware, or upgrading from Astro 5/6. versions: astro: "7" node: "22.12+" @@ -11,7 +11,7 @@ related-skills: astro-content, astro-actions, astro-islands, astro-integrations, --- -Configures and explains Astro 7 (stable, 7.0.9) core framework mechanics: file-based routing, the three output modes (static/server/hybrid) and per-route `prerender`, middleware for auth/redirects/headers, the Vite Environment API, the single Rust compiler (Go compiler removed, strict HTML parsing), stable Content Security Policy, Live Content Collections, and the built-in Fonts API. +Configures and explains Astro 7 (stable, 7.3.5) core framework mechanics: file-based routing, the two output modes (`static`/`server`) plus hybrid rendering via per-route `prerender`, middleware for auth/redirects/headers, the Vite Environment API, the single Rust compiler (Go compiler removed, strict HTML parsing), stable Content Security Policy, Live Content Collections, and the built-in Fonts API. Covers initial project setup and migration from Astro 5/6, including breaking changes and Node 22.12+ requirements. Does not cover Content Layer API details (astro-content), Server Actions (astro-actions), Islands hydration directives (astro-islands), UI framework integrations (astro-integrations), or deployment adapters (astro-deployment) — those live in their own skills. @@ -38,7 +38,7 @@ After implementation, run **fuse-ai-pilot:sniper** for validation. - Building new content-driven websites or blogs - Migrating from Astro 6 to version 7 -- Configuring static, server, or hybrid output modes +- Configuring static or server output (hybrid = per-route `prerender`) - Setting up middleware for auth or redirects - Leveraging the new Rust compiler for large sites - Implementing Content Security Policy (CSP) headers @@ -54,6 +54,8 @@ After implementation, run **fuse-ai-pilot:sniper** for validation. | Built-in Fonts API (stable) | Zero-config font loading with performance optimization | | CSP Support (stable) | Built-in Content Security Policy nonce management | | Cloudflare Workers | First-class support with workerd runtime in dev | +| Route caching (stable in 7.0) | Top-level `cache` + `routeRules`, `Astro.cache.set({ maxAge, swr, tags })` | +| Advanced Routing (7.0) | Optional `src/fetch.ts` entrypoint (`astro/fetch`, `astro/hono`) | --- @@ -65,7 +67,7 @@ After implementation, run **fuse-ai-pilot:sniper** for validation. |------|-------------|----------| | `static` (default) | All pages prerendered at build | Blogs, docs, marketing | | `server` | All pages rendered on demand | Apps, dashboards, auth | -| `hybrid` | Mix static + on-demand | Most production sites | +| Hybrid (not an `output` value) | `static` or `server` + per-route `export const prerender` | Most production sites | ### Routing @@ -94,8 +96,8 @@ After implementation, run **fuse-ai-pilot:sniper** for validation. ## Best Practices 1. **Use `output: 'static'` by default** — Add server only when needed -2. **Per-route `prerender`** — Fine-grained control in hybrid mode +2. **Per-route `prerender`** — Fine-grained hybrid control (`output` only accepts `'static' | 'server'`; there is no `'hybrid'` value) 3. **Middleware for cross-cutting concerns** — Auth, redirects, headers 4. **No compiler flag needed** — the Rust compiler is the only compiler now (Go removed); watch for strict HTML parsing errors on unclosed tags -5. **CSP nonces** — Use built-in stable support instead of custom headers +5. **CSP hashes** — Use built-in stable `security.csp` (hash-based, plus the `Astro.csp` runtime API) instead of custom headers 6. **Node 22.12+ required** — odd-numbered Node versions are unsupported; stay on stable TypeScript tooling, the native `tsgo` compiler can make `astro check`/typecheck fail opaquely (see installation.md) diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/config.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/config.md index 55ffdf9..bcde7c5 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/config.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/config.md @@ -6,7 +6,7 @@ keywords: config, defineConfig, integrations, vite, base, site, server priority: high --- -# Astro 6 Configuration +# Astro 7 Configuration ## When to Use @@ -23,7 +23,7 @@ import { defineConfig } from 'astro/config'; export default defineConfig({ site: 'https://example.com', base: '/', - output: 'static', // 'static' | 'server' | 'hybrid' + output: 'static', // 'static' | 'server' (no 'hybrid' — use per-route prerender) trailingSlash: 'ignore', // 'always' | 'never' | 'ignore' compressHTML: 'jsx', // default in Astro 7 — JSX-style whitespace stripping }); @@ -41,6 +41,10 @@ export default defineConfig({ | `adapter` | object | Server runtime adapter | | `vite` | object | Vite config passthrough (Vite 8) | | `srcDir` | string | Source directory (default: `./src`) | +| `session` | `object \| false` | Session driver config; `false` opts out entirely (7.2+) — runtime tree-shaken, adapters skip their default driver | +| `logger.entrypoint` | `URL \| string` | Custom logger module (option since 7.0; URL form 7.1+, relative string 7.2+) | +| `fetchFile` | `string \| null` | Advanced Routing entrypoint (default `src/fetch.ts`); `null` disables it | +| `cache` / `routeRules` | object | Stable route caching (7.0), e.g. `cache: { provider: memoryCache() }` | | `publicDir` | string | Public assets (default: `./public`) | ## Removed Experimental Flags (Astro 7) diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/installation.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/installation.md index f598087..51d9a41 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/installation.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/installation.md @@ -1,24 +1,24 @@ --- name: installation -description: Astro 6 installation, upgrade from v5, Node requirements -when-to-use: new project, upgrading from Astro 5, setting up TypeScript +description: Astro 7 installation, upgrade from v5/v6, Node requirements +when-to-use: new project, upgrading from Astro 5/6, setting up TypeScript keywords: setup, init, create, upgrade, node, requirements priority: high --- -# Astro 6 Installation +# Astro 7 Installation ## When to Use -- Starting a new Astro 6 project -- Upgrading from Astro 4/5 -- Configuring Node 22+ environment +- Starting a new Astro 7 project (latest stable: 7.3.5) +- Upgrading from Astro 5/6 (see the official v7 upgrade guide) +- Configuring Node 22.12+ environment ## Requirements | Requirement | Version | |-------------|---------| -| Node.js | 22.12+ (odd-numbered Node versions unsupported) | +| Node.js | 22.12+ (`engines.node >=22.12.0`; odd-numbered Node versions unsupported) | | TypeScript | 5.1+ | ## TS7 / `tsgo` Warning diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/middleware.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/middleware.md index 4a59692..4537366 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/middleware.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/middleware.md @@ -1,12 +1,12 @@ --- name: middleware -description: Astro 6 middleware — request/response interception, auth, redirects, locals +description: Astro 7 middleware — request/response interception, auth, redirects, locals when-to-use: auth guards, redirects, request logging, setting locals keywords: middleware, locals, auth, redirect, request, response priority: medium --- -# Astro 6 Middleware +# Astro 7 Middleware ## When to Use diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/new-features.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/new-features.md index 3a803d8..8877e39 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/new-features.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/new-features.md @@ -10,7 +10,7 @@ priority: medium ## When to Use -- Leveraging new Astro 6 stable features +- Leveraging Astro 6/7 stable features (7.1–7.3 additions at the end) - Setting up font optimization - Implementing Content Security Policy - Using Live Content Collections for real-time data @@ -40,28 +40,51 @@ export default defineConfig({ ## Content Security Policy (stable) -CSP is stable since Astro 6.0 — `experimental.csp` no longer exists, configure it as a top-level option: +CSP is stable since Astro 6.0 — `experimental.csp` no longer exists, configure it under `security.csp`: ```typescript export default defineConfig({ - csp: true, // Generates nonces automatically + security: { + csp: true, // Hash-based: auto-hashes bundled scripts/styles (SHA-256 default) + }, }); ``` ## Live Content Collections -Fetch real-time external data through the content layer: +Fetch real-time external data at request time (adapter required). Live collections live in `src/live.config.ts` (not `content.config.ts`) and use `defineLiveCollection()`: ```typescript -// src/content.config.ts -import { defineCollection } from 'astro:content'; +// src/live.config.ts +import { defineLiveCollection } from 'astro:content'; import { myLiveLoader } from './loaders/live'; -const news = defineCollection({ +const news = defineLiveCollection({ loader: myLiveLoader({ url: 'https://api.example.com/news' }), }); + +export const collections = { news }; ``` +Query with `getLiveCollection()` / `getLiveEntry()`. + ## Single Rust Compiler (Astro 7) Astro 7 removed the Go compiler entirely — the Rust compiler is now the only `.astro` file compiler, no flag needed (`experimental.rustCompiler` no longer exists). It also enforces **strict HTML parsing**: unclosed tags and invalid HTML now raise a build error instead of being silently auto-corrected. Audit existing `.astro` templates for unclosed tags before upgrading. + +## Astro 7.1 – 7.3 Additions + +| Version | Feature | Usage | +|---------|---------|-------| +| 7.1 | Fine-grained CSP directives | `kind: 'element' \| 'attribute'` on CSP hashes/resources → `script-src-elem`, `script-src-attr`, `style-src-elem`, `style-src-attr` | +| 7.1 | Pagination URL control | `paginate(items, { pageSize, format: (url) => url + '.html' })` | +| 7.1 | Multiple dev servers | `astro dev --ignore-lock` (bypasses the dev lockfile) | +| 7.1 | Lower sync memory | `glob({ ..., deferRender: true })` renders entries on demand | +| 7.1 | Logger entrypoint as URL (option exists since 7.0) | `logger: { entrypoint: new URL('./src/custom-logger.js', import.meta.url) }` + `AstroRuntimeLogger` type | +| 7.2 | Opt out of sessions | `session: false` — session runtime removed from the SSR bundle | +| 7.2 | Background preview | `astro preview --background`, then `astro preview status \| logs \| stop` | +| 7.2 | Relative logger entrypoint | `logger: { entrypoint: './src/custom-logger.js' }` | +| 7.3 | Multiple preview servers | `astro preview --ignore-lock` | +| 7.3 | Logger in extension points | Custom image services (`transform(..., logger)`) and cache providers (`onRequest({ logger }, next)`) receive Astro's logger | + +Experimental (opt-in, not stable): `experimental.collectionStorage: 'chunked'` (7.1) and `experimental.incrementalBuild` + per-path `cacheKey` in `getStaticPaths()` (7.2). diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/output-modes.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/output-modes.md index 0352c11..dcdb830 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/output-modes.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/output-modes.md @@ -1,12 +1,12 @@ --- name: output-modes -description: Astro 6 output modes — static, server, hybrid — and when to use each +description: Astro 7 output modes — static, server, and hybrid rendering via per-route prerender — and when to use each when-to-use: configuring project output, choosing rendering strategy keywords: output, static, server, hybrid, prerender, SSR, SSG priority: high --- -# Astro 6 Output Modes +# Astro 7 Output Modes ## When to Use @@ -20,7 +20,9 @@ priority: high |------|--------|----------| | `static` | Default | All pages prerendered at build time | | `server` | `output: 'server'` | All pages rendered on demand | -| `hybrid` | `output: 'hybrid'` | Static by default, opt-in to server per route | +| Hybrid | `output: 'static'` + adapter | Static by default, opt-in to on-demand per route with `prerender = false` | + +`output` only accepts `'static' | 'server'` — the former `'hybrid'` value was merged into `'static'` (Astro 5) and is invalid in Astro 7. ## Configuration @@ -30,7 +32,7 @@ import { defineConfig } from 'astro/config'; import node from '@astrojs/node'; export default defineConfig({ - output: 'server', // or 'hybrid' + output: 'server', // or 'static' (default) + per-route prerender = false adapter: node({ mode: 'standalone' }), }); ``` @@ -44,7 +46,7 @@ export const prerender = true; --- --- -// In 'hybrid' mode — this route is server-rendered +// In 'static' mode (with an adapter) — this route is rendered on demand export const prerender = false; --- ``` diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/routing.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/routing.md index 634bebe..42446c5 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/routing.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/routing.md @@ -1,12 +1,12 @@ --- name: routing -description: Astro 6 file-based routing, dynamic routes, catch-all routes, endpoints +description: Astro 7 file-based routing, dynamic routes, catch-all routes, endpoints when-to-use: creating pages, dynamic routes, API endpoints keywords: routing, pages, dynamic, slug, catch-all, endpoint priority: high --- -# Astro 6 Routing +# Astro 7 Routing ## When to Use @@ -43,11 +43,26 @@ const { slug } = Astro.params; --- ``` +## Pagination URL Format (7.1+) + +`paginate()` accepts a `format` function to rewrite the generated `next`/`prev`/`first`/`last` URLs (e.g. for `build.format: 'file'` hosts without rewrites): + +```astro +--- +import { getCollection } from 'astro:content'; + +export async function getStaticPaths({ paginate }) { + const posts = await getCollection('blog'); + return paginate(posts, { pageSize: 10, format: (url) => `${url}.html` }); +} +--- +``` + ## Per-Route Prerender Override ```astro --- -// In hybrid/server mode: opt out of prerendering +// In static mode (with an adapter): render this route on demand export const prerender = false; --- @@ -71,3 +86,15 @@ export function GET({ request }) { ## `src/fetch.ts` (Advanced Routing) Reserved file, structured like `src/middleware.ts`, for advanced routing scenarios. Its resolution is controlled by the `fetchFile` config option, which can override the path or be set to `null` to disable it. + +```ts +// src/fetch.ts +import { astro, FetchState } from 'astro/fetch'; + +export default { + fetch(request: Request) { + const state = new FetchState(request); + return astro(state); // or compose astro/hono handlers: actions(), middleware(), pages(), i18n() + }, +}; +``` diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/templates/basic-setup.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/templates/basic-setup.md index 5a00d44..0eb6f18 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/templates/basic-setup.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/templates/basic-setup.md @@ -1,11 +1,11 @@ --- name: basic-setup -description: Complete Astro 6 project setup with TypeScript, output mode, and layout -when-to-use: starting a new Astro 6 project from scratch +description: Complete Astro 7 project setup with TypeScript, output mode, and layout +when-to-use: starting a new Astro 7 project from scratch keywords: setup, project, layout, typescript, config --- -# Astro 6 Basic Project Setup +# Astro 7 Basic Project Setup ## Project Structure @@ -68,7 +68,7 @@ const { title, description = 'My Astro site' } = Astro.props; import BaseLayout from '../layouts/BaseLayout.astro'; --- -

Welcome to Astro 6

+

Welcome to Astro 7

``` diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/templates/config-example.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/templates/config-example.md index 047f7cf..645c890 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/templates/config-example.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-7/references/templates/config-example.md @@ -1,11 +1,11 @@ --- name: config-example -description: astro.config.ts examples for static, server, and hybrid modes with adapters +description: astro.config.ts examples for static, server, and hybrid (per-route prerender) setups with adapters when-to-use: configuring Astro output mode with adapter keywords: config, adapter, node, cloudflare, vercel, netlify, hybrid --- -# Astro 6 Config Examples +# Astro 7 Config Examples ## Static (Default) @@ -30,29 +30,31 @@ export default defineConfig({ }); ``` -## Hybrid Mode (Cloudflare) +## Hybrid (Cloudflare) + +There is no `output: 'hybrid'` — keep `output: 'static'` (default) and opt routes into on-demand rendering with `export const prerender = false`. ```typescript import { defineConfig } from 'astro/config'; -import cloudflare from '@astrojs/cloudflare'; +import cloudflare from '@astrojs/cloudflare'; // v14+ for Astro 7 import react from '@astrojs/react'; export default defineConfig({ - output: 'hybrid', - adapter: cloudflare({ mode: 'directory' }), + output: 'static', + adapter: cloudflare(), integrations: [react()], }); ``` ## Stable Fonts + CSP (Astro 7) -`fonts` and `csp` are stable top-level options — no `experimental` wrapper. The Rust compiler is now the only compiler and needs no flag. +`fonts` (top-level) and `security.csp` are stable — no `experimental` wrapper. The Rust compiler is now the only compiler and needs no flag. ```typescript import { defineConfig, fontProviders } from 'astro/config'; export default defineConfig({ - csp: true, + security: { csp: true }, fonts: [{ provider: fontProviders.google(), name: 'Inter', diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-assets/SKILL.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-assets/SKILL.md index 1470c31..1f9b063 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-assets/SKILL.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-assets/SKILL.md @@ -24,7 +24,7 @@ Before ANY implementation, use `TeamCreate` to spawn 3 agents: 1. **fuse-ai-pilot:explore-codebase** - Analyze existing image usage and asset patterns 2. **fuse-ai-pilot:research-expert** - Verify astro:assets API via Context7/Exa -3. **mcp__context7__query-docs** - Check Astro 6 Fonts API and image component docs +3. **mcp__context7__query-docs** - Check Astro 7 Fonts API and image component docs After implementation, run **fuse-ai-pilot:sniper** for validation. diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-assets/references/fonts-api.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-assets/references/fonts-api.md index 4431be6..8d88af9 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-assets/references/fonts-api.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-assets/references/fonts-api.md @@ -99,7 +99,7 @@ export default defineConfig({ ## Key Behaviors - Stable since Astro 6.0 — no `experimental` flag, safe for production use -- Automatic `font-display: optional` to eliminate CLS +- `font-display` defaults to `swap` (configurable per font via `display`); optimized fallbacks (`optimizedFallbacks`) limit CLS - Fonts subsetted and served locally at build time - `preload` on `` component adds `` - No external CDN requests in production diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-assets/references/templates/image-setup.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-assets/references/templates/image-setup.md index 95bc1ba..c1586ec 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-assets/references/templates/image-setup.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-assets/references/templates/image-setup.md @@ -1,6 +1,6 @@ --- name: image-setup-template -description: Complete image optimization setup for Astro 6 with sharp, responsive images, and fonts +description: Complete image optimization setup for Astro 7 with sharp, responsive images, and fonts type: template --- @@ -9,7 +9,7 @@ type: template ## astro.config.mjs ```js -import { defineConfig } from 'astro/config'; +import { defineConfig, fontProviders } from 'astro/config'; export default defineConfig({ image: { @@ -17,15 +17,14 @@ export default defineConfig({ domains: ['images.unsplash.com', 'cdn.example.com'], remotePatterns: [{ protocol: 'https', hostname: '*.cloudinary.com' }], }, - experimental: { - fonts: [ - { - provider: 'google', - name: 'Inter', - cssVariable: '--font-sans', - }, - ], - }, + // Stable top-level option since Astro 6.0 (no experimental wrapper) + fonts: [ + { + provider: fontProviders.google(), + name: 'Inter', + cssVariable: '--font-sans', + }, + ], }); ``` diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-content/references/loaders.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-content/references/loaders.md index 79e45c9..c1c2c71 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-content/references/loaders.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-content/references/loaders.md @@ -31,6 +31,14 @@ const blog = defineCollection({ Supports: `.md`, `.mdx`, `.json`, `.yaml`, `.yml`, `.toml` +### `deferRender` (Astro 7.1+) + +By default `glob()` renders Markdown during sync and caches the HTML. For large collections, `deferRender: true` stores entries unrendered and renders on demand (like `.mdx`), lowering sync memory at the cost of cross-build HTML caching: + +```typescript +loader: glob({ pattern: '**/*.md', base: './src/content/docs', deferRender: true }), +``` + ## file() Loader ```typescript diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-content/references/mdx.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-content/references/mdx.md index ed1a7a8..fd28bb6 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-content/references/mdx.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-content/references/mdx.md @@ -22,25 +22,33 @@ Astro 7 switched the default Markdown renderer to **Sätteri** (PR #16966); `@as ```bash npx astro add mdx +# Only if you need remark/rehype plugins (unified pipeline): +npm install @astrojs/markdown-remark ``` ```typescript // astro.config.ts import { defineConfig } from 'astro/config'; import mdx from '@astrojs/mdx'; -import remarkGfm from 'remark-gfm'; +import { unified } from '@astrojs/markdown-remark'; +import remarkToc from 'remark-toc'; import rehypePrettyCode from 'rehype-pretty-code'; export default defineConfig({ integrations: [ + // `processor` (mdx 6+): MDX inherits `markdown.processor` by default; override it here mdx({ - remarkPlugins: [remarkGfm], - rehypePlugins: [[rehypePrettyCode, { theme: 'github-dark' }]], + processor: unified({ + remarkPlugins: [remarkToc], + rehypePlugins: [[rehypePrettyCode, { theme: 'github-dark' }]], + }), }), ], }); ``` +Top-level `markdown.remarkPlugins` / `markdown.rehypePlugins` are deprecated in Astro 7 (still work only with `@astrojs/markdown-remark` installed) — pass plugins to the processor instead. Sätteri has GFM, SmartyPants, heading IDs, math, and directives built in, and its own `mdastPlugins` / `hastPlugins` API (`satteri()` from `@astrojs/markdown-satteri`). + ## Using Components in MDX ```mdx @@ -69,7 +77,7 @@ const blog = defineCollection({ | Plugin | Purpose | |--------|---------| -| `remark-gfm` | GitHub-flavored Markdown (tables, strikethrough) | +| `remark-gfm` | GitHub-flavored Markdown (tables, strikethrough) — built into Sätteri and on by default | | `remark-toc` | Auto-generate table of contents | | `rehype-pretty-code` | Syntax highlighting | | `rehype-slug` | Auto-add IDs to headings | diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-db/SKILL.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-db/SKILL.md index 52074b1..49f477b 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-db/SKILL.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-db/SKILL.md @@ -11,14 +11,14 @@ related-skills: astro-7, astro-actions, astro-deployment Implements Astro DB (`@astrojs/db`): schema definition with `defineDb`/`defineTable` in `db/config.ts`, column types (`text`, `number`, `boolean`, `date`, `json`), type-safe CRUD via `db.select/insert/update/delete`, development seeding in `db/seed.ts`, and production deployment to Turso (libSQL) with `ASTRO_DB_REMOTE_URL`/`ASTRO_DB_APP_TOKEN` and `astro db push`. -Also covers integration with Astro Actions for end-to-end type-safe form-to-database flows. `@astrojs/db` is deprecated and no longer actively maintained (still published, v0.21.3, not removed from Astro 7) — for new projects this skill recommends Drizzle, Kysely, or a direct libSQL client instead; existing projects can keep using it but should plan a migration. +Also covers integration with Astro Actions for end-to-end type-safe form-to-database flows. `@astrojs/db` is deprecated on npm (last release v0.21.3, June 2026) and listed as **Removed** in the official Astro v7 upgrade guide — for new projects this skill recommends Drizzle, Kysely, `node:sqlite`, or a direct libSQL client instead; existing Astro 6 projects must migrate off it before upgrading to Astro 7. # Astro DB Type-safe SQL database built into Astro, powered by libSQL/Turso. Use for structured data without external backend services. -> **⚠️ Deprecation notice**: `@astrojs/db` is **deprecated and no longer actively maintained** (still published on npm, currently v0.21.3 — it has not been removed from Astro 7). For new projects, prefer **Drizzle**, **Kysely**, or a direct **libSQL** client instead. Existing projects can keep using it, but should plan a migration. +> **⚠️ Removal notice**: `@astrojs/db` is **deprecated on npm** ("Use a database client (Drizzle, Kysely, etc.) directly instead"; last release v0.21.3) and the **official Astro v7 upgrade guide lists it under "Removed"** — remove it from dependencies when upgrading. Replacements: Node's built-in **`node:sqlite`** (Node adapter), **Drizzle** directly, **Kysely**, or a **libSQL/Turso** client. The content below documents the legacy Astro 6 API for maintaining/migrating existing projects. ## Agent Workflow (MANDATORY) @@ -100,4 +100,4 @@ Combine with `astro:actions` for end-to-end type safety: Zod input validation 3. **`.returning()` after insert** - Get back inserted rows 4. **Push before deploy** - Run `astro db push` in CI/CD 5. **Turso free tier** - 500 databases, generous for production -6. **New projects: consider Drizzle/Kysely/libSQL instead** - `@astrojs/db` is deprecated and unmaintained; still usable for existing projects, but not recommended as a starting point +6. **New projects: use Drizzle/Kysely/`node:sqlite`/libSQL instead** - `@astrojs/db` is deprecated and listed as removed in the Astro v7 upgrade guide; migrate existing projects before upgrading to Astro 7 diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/SKILL.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/SKILL.md index 4e5ce6e..3d02797 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/SKILL.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/SKILL.md @@ -9,9 +9,9 @@ related-skills: astro-7, astro-db, astro-islands --- -Configures Astro 7 deployment across the four major adapters: `@astrojs/cloudflare` (Workers runtime, D1/KV/R2 bindings, workerd local dev via `platformProxy`, v13+ required), `@astrojs/vercel` (Serverless/Edge, built-in Image CDN, skew protection), `@astrojs/netlify` (Deno-based Edge Functions), and `@astrojs/node` (standalone server). +Configures Astro 7 deployment across the four major adapters: `@astrojs/cloudflare` v14 (Workers runtime, D1/KV/R2 bindings via `cloudflare:workers`, `astro dev` on workerd through the Cloudflare Vite plugin), `@astrojs/vercel` v11 (Serverless/Edge, built-in Image CDN, skew protection), `@astrojs/netlify` v8 (Deno-based Edge Functions), and `@astrojs/node` v11 (standalone server). -Also covers output-mode selection (`static`/`server`, per-page `prerender`), ISR patterns implemented via platform caching (Cloudflare KV or Vercel `stale-while-revalidate`, since Astro has no native ISR), and edge middleware for auth/redirects/A-B testing. Does not cover Astro DB setup itself (astro-db) or Islands hydration directives (astro-islands) beyond what's needed to pick a server adapter. +Also covers output-mode selection (`static`/`server`, per-page `prerender`), Astro 7's stable route caching (`cache` provider + `routeRules`, experimental CDN providers per adapter) alongside platform ISR (Vercel `isr`, Cloudflare KV, `stale-while-revalidate` headers), and edge middleware for auth/redirects/A-B testing. Does not cover Astro DB setup itself (astro-db) or Islands hydration directives (astro-islands) beyond what's needed to pick a server adapter. # Astro Deployment @@ -45,10 +45,10 @@ After implementation, run **fuse-ai-pilot:sniper** for validation. | Platform | Package | Runtime | Notes | |----------|---------|---------|-------| -| Cloudflare | `@astrojs/cloudflare` v13+ | workerd | Astro 6: `astro dev` runs on workerd | -| Vercel | `@astrojs/vercel` | Node/Edge | Image CDN built-in | -| Netlify | `@astrojs/netlify` | Edge | Deno-based edge functions | -| Node.js | `@astrojs/node` | Node | Standalone server mode | +| Cloudflare | `@astrojs/cloudflare` v14 (Astro 7) | workerd | `astro dev` runs on workerd since Astro 6 (v13) | +| Vercel | `@astrojs/vercel` v11 | Node/Edge | Image CDN built-in | +| Netlify | `@astrojs/netlify` v8 | Edge | Deno-based edge functions | +| Node.js | `@astrojs/node` v11 | Node | Standalone server mode | --- @@ -62,11 +62,11 @@ After implementation, run **fuse-ai-pilot:sniper** for validation. ### Cloudflare Astro -Astro 6 runs `astro dev` on workerd — same runtime as production. Enables D1, KV, R2 bindings in local dev via `platformProxy`. No more simulation gaps. Requires `@astrojs/cloudflare` v13+ and Node.js 22+. +Since Astro 6, `astro dev` and `astro preview` run on workerd via the Cloudflare Vite plugin — same runtime as production, so D1, KV, R2 bindings work locally without `platformProxy` (no longer a documented adapter option). Access bindings with `import { env } from 'cloudflare:workers'` (`Astro.locals.runtime` was removed). Astro 7 requires `@astrojs/cloudflare` v14 (v13 peers `astro ^6`) and Node.js 22.12+. ### ISR Pattern -Astro has no native ISR. Implement with platform caching: Cloudflare KV as cache layer, or Vercel's `Cache-Control` with `stale-while-revalidate`. +Astro 7 ships stable route caching: set a `cache.provider` (`memoryCache()`, or the experimental `cacheVercel()` / `cacheNetlify()` / `cacheCloudflare()` CDN providers) and call `Astro.cache.set({ maxAge, swr, tags })` or declare `routeRules`. Platform alternatives remain: Vercel `isr`, Cloudflare KV as cache layer, or `Cache-Control` with `stale-while-revalidate`. ### Skew Protection @@ -99,7 +99,7 @@ On Vercel, enable skew protection to prevent asset mismatches between old client ## Best Practices 1. **Match adapter to platform early** - Switching adapters mid-project is painful -2. **Cloudflare: use v13+ for Astro 7** - Required for workerd local dev -3. **Node.js 22+ for Astro 7** - Drops Node 18/20 support +2. **Cloudflare: use v14 for Astro 7** - v13 targets Astro 6; workerd local dev since v13 +3. **Node.js 22.12+ for Astro 7** - `engines.node >=22.12.0`; Node 18/20 unsupported 4. **Per-page prerender** - Mix static and SSR for optimal performance -5. **Test bindings locally** - Cloudflare platformProxy enables local D1/KV/R2 +5. **Test bindings locally** - `astro dev` on workerd exposes local D1/KV/R2 (no `platformProxy` needed) diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/cloudflare-adapter.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/cloudflare-adapter.md index 591b00e..0a66e1c 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/cloudflare-adapter.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/cloudflare-adapter.md @@ -1,8 +1,8 @@ --- name: cloudflare-adapter -description: "@astrojs/cloudflare v13+ adapter for Astro 6 — Workers, D1, KV, R2, wrangler config" +description: "@astrojs/cloudflare v14 adapter for Astro 7 — Workers, D1, KV, R2, wrangler config" when-to-use: Deploying Astro to Cloudflare Workers with platform bindings -keywords: Cloudflare, Workers, D1, KV, R2, wrangler, platformProxy, astrojs/cloudflare +keywords: Cloudflare, Workers, D1, KV, R2, wrangler, cloudflare:workers, astrojs/cloudflare priority: high --- @@ -12,14 +12,14 @@ priority: high - Deploying to Cloudflare Workers (edge computing) - Using Cloudflare D1 (SQLite), KV (key-value), or R2 (object storage) -- Astro 6: `astro dev` runs on workerd (same as production) +- Since Astro 6: `astro dev` / `astro preview` run on workerd (same as production) ## Requirements -- `@astrojs/cloudflare` v13+ -- Astro 6+ -- Node.js 22+ -- Wrangler 4.x +- `@astrojs/cloudflare` v14 for Astro 7 (v13 targets Astro 6) +- Astro 7.2+ (peer range of v14) +- Node.js 22.12+ +- Wrangler 4.x (peer `^4.125.0`) ## Install @@ -36,14 +36,17 @@ import cloudflare from '@astrojs/cloudflare'; export default defineConfig({ output: 'server', adapter: cloudflare({ - imageService: 'cloudflare', // Use Cloudflare's image resizing - platformProxy: { enabled: true }, // Enable D1/KV/R2 in dev + imageService: 'cloudflare-binding', // default since v13 (Cloudflare Images binding) }), }); ``` +Local bindings (D1/KV/R2) work in `astro dev` out of the box — the adapter runs the Cloudflare Vite plugin on workerd; `platformProxy` is no longer a documented option. + ## wrangler.toml +Optional for simple projects (Astro generates a default config). `wrangler.jsonc` is also supported and is what the official docs use. + ```toml name = "my-astro-app" compatibility_date = "2024-09-23" @@ -67,7 +70,8 @@ bucket_name = "my-bucket" ```ts // In .astro frontmatter or API routes -const { DB, KV, STORAGE } = Astro.locals.runtime.env; +import { env } from 'cloudflare:workers'; +const { DB, KV } = env; // D1 query const result = await DB.prepare('SELECT * FROM posts').all(); @@ -75,6 +79,10 @@ const result = await DB.prepare('SELECT * FROM posts').all(); // KV get/set await KV.put('key', 'value'); const val = await KV.get('key'); + +// cf object and execution context +const country = Astro.request.cf?.country; +Astro.locals.cfContext.waitUntil(somePromise); ``` ## Per-Page Prerender @@ -85,6 +93,24 @@ export const prerender = true; // Static export const prerender = false; // SSR (default in server mode) ``` -## Key Breaking Change (Astro 6) +## Key Breaking Change (Astro 6 / adapter v13) + +`Astro.locals.runtime` was removed: use `import { env } from 'cloudflare:workers'` for env/bindings, `Astro.request.cf` for the `cf` object, global `caches`, and `Astro.locals.cfContext` for the `ExecutionContext`. Cloudflare Pages deployment is no longer supported (Workers only). `Astro.glob()` removed — use `import.meta.glob()`. -`Astro.locals.runtime` API replaced. Access via `Astro.locals.runtime.env` directly. `Astro.glob()` removed — use `import.meta.glob()`. +## Astro 7.3: `finalize()` for Custom Worker Entrypoints + +With `@astrojs/cloudflare` 14.3+, custom `astro/fetch` pipelines should pass the response through `finalize()` to apply cookies and CDN cache defaults: + +```ts +import { astro, FetchState } from 'astro/fetch'; +import { cf, finalize } from '@astrojs/cloudflare/fetch'; + +export default { + async fetch(request: Request, env: Env, ctx: ExecutionContext) { + const state = new FetchState(request); + const asset = await cf(state, env, ctx); + if (asset) return asset; + return finalize(state, await astro(state)); + }, +}; +``` diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/edge-middleware.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/edge-middleware.md index 2fe1c2f..38fd980 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/edge-middleware.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/edge-middleware.md @@ -42,8 +42,8 @@ export const onRequest = defineMiddleware(async (context, next) => { import { defineMiddleware } from 'astro:middleware'; export const onRequest = defineMiddleware(async (context, next) => { - const runtime = context.locals.runtime; - const country = runtime?.cf?.country ?? 'US'; + // Astro.locals.runtime was removed in @astrojs/cloudflare v13 — read cf from the request + const country = context.request.cf?.country ?? 'US'; // Redirect to locale-specific page if (context.url.pathname === '/' && country === 'FR') { diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/isr-patterns.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/isr-patterns.md index 64fdd37..c4c6eeb 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/isr-patterns.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/isr-patterns.md @@ -14,7 +14,36 @@ priority: medium - Avoiding full site rebuilds for content updates - High-traffic pages needing both freshness and performance -## Astro Has No Native ISR +## Route Caching (Astro 7, stable) + +Astro has no Vercel-style ISR, but since 7.0 it ships a stable, platform-agnostic route cache for on-demand routes: + +```js +// astro.config.mjs +import { defineConfig, memoryCache } from 'astro/config'; +import node from '@astrojs/node'; + +export default defineConfig({ + adapter: node({ mode: 'standalone' }), + cache: { provider: memoryCache() }, // or cacheVercel() / cacheNetlify() / cacheCloudflare() (experimental CDN providers) + routeRules: { + '/blog/[...path]': { maxAge: 300, swr: 60 }, + }, +}); +``` + +```astro +--- +export const prerender = false; +if (Astro.cache.enabled) { + Astro.cache.set({ maxAge: 120, swr: 60, tags: ['home'] }); // context.cache in endpoints/middleware +} +--- +``` + +Invalidate with `cache.invalidate({ path })` or by tag. CDN providers: `@astrojs/vercel/cache` (v11+), `@astrojs/netlify/cache` (v8+), `@astrojs/cloudflare/cache` (v14+). + +## Platform Caching Alternatives Implement ISR-like behavior using platform caching: @@ -49,9 +78,10 @@ export async function GET() { ```ts // src/pages/api/blog/[slug].ts import type { APIRoute } from 'astro'; +import { env } from 'cloudflare:workers'; -export const GET: APIRoute = async ({ params, locals }) => { - const { KV } = locals.runtime.env; +export const GET: APIRoute = async ({ params }) => { + const { KV } = env; const cacheKey = `post:${params.slug}`; // Check cache first @@ -88,6 +118,7 @@ return new Response(html, { | Need | Solution | |------|----------| +| Any adapter, Astro 7 | `cache` provider + `Astro.cache.set()` / `routeRules` | | Vercel + simple TTL | Vercel ISR adapter option | | Cloudflare + fine control | KV cache with manual invalidation | | Any platform + headers | `Cache-Control: s-maxage + stale-while-revalidate` | diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/netlify-adapter.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/netlify-adapter.md index 425ceba..1b9b4d8 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/netlify-adapter.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/netlify-adapter.md @@ -29,7 +29,7 @@ import netlify from '@astrojs/netlify'; export default defineConfig({ output: 'server', adapter: netlify({ - edgeMiddleware: true, // Run middleware at edge + middlewareMode: 'edge', // Run middleware on Edge Functions (replaces edgeMiddleware) imageCDN: true, // Use Netlify Image CDN }), }); diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/templates/cloudflare-setup.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/templates/cloudflare-setup.md index 3f18300..860e99e 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/templates/cloudflare-setup.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/templates/cloudflare-setup.md @@ -1,6 +1,6 @@ --- name: cloudflare-setup-template -description: Complete Cloudflare Workers setup for Astro 6 with D1, KV, and R2 bindings +description: Complete Cloudflare Workers setup for Astro 7 (@astrojs/cloudflare v14) with D1, KV, and R2 bindings type: template --- @@ -25,16 +25,19 @@ export default defineConfig({ output: 'server', adapter: cloudflare({ imageService: 'cloudflare', - platformProxy: { enabled: true }, }), }); ``` +Bindings work in `astro dev` (workerd) without extra options — `platformProxy` is no longer a documented adapter option. + ## wrangler.toml +`main` is optional: when set, it must point to `@astrojs/cloudflare/entrypoints/server` (or your custom worker), not a built file. + ```toml name = "my-astro-app" -main = "./dist/server/index.js" +main = "@astrojs/cloudflare/entrypoints/server" compatibility_date = "2024-09-23" compatibility_flags = ["nodejs_compat"] @@ -66,9 +69,10 @@ CLOUDFLARE_ACCOUNT_ID=your-account-id ```ts import type { APIRoute } from 'astro'; +import { env } from 'cloudflare:workers'; -export const GET: APIRoute = async ({ locals }) => { - const { DB, CACHE } = locals.runtime.env; +export const GET: APIRoute = async () => { + const { DB, CACHE } = env; // Try cache first const cached = await CACHE.get('data'); diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/templates/vercel-setup.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/templates/vercel-setup.md index 1787a9b..eac6d55 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/templates/vercel-setup.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/templates/vercel-setup.md @@ -1,6 +1,6 @@ --- name: vercel-setup-template -description: Complete Vercel setup for Astro 6 with Image CDN, ISR, and edge functions +description: Complete Vercel setup for Astro 7 (@astrojs/vercel v11) with Image CDN, ISR, and edge functions type: template --- @@ -28,7 +28,7 @@ export default defineConfig({ bypassToken: process.env.ISR_BYPASS_TOKEN, }, skewProtection: true, // Prevent asset mismatch on deploy - edgeMiddleware: false, // true = run middleware on edge + middlewareMode: 'classic', // 'edge' = run middleware as an edge function (replaces edgeMiddleware) }), }); ``` diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/vercel-adapter.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/vercel-adapter.md index 99dad47..923f5e6 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/vercel-adapter.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-deployment/references/vercel-adapter.md @@ -32,7 +32,7 @@ export default defineConfig({ imageService: true, // Use Vercel Image CDN isr: true, // Enable ISR skewProtection: true, // Prevent asset mismatches on deploy - edgeMiddleware: false, // Run middleware at edge (optional) + // middlewareMode: 'edge', // Run middleware as an edge function (replaces edgeMiddleware) }), }); ``` diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/content-translation.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/content-translation.md index 3b14b7f..1a13f63 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/content-translation.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/content-translation.md @@ -12,7 +12,7 @@ src/content/ ├── en/ │ ├── getting-started.mdx │ └── tutorial.mdx - ├── fr/ + ├── it/ │ ├── getting-started.mdx │ └── tutorial.mdx └── es/ @@ -20,7 +20,7 @@ src/content/ ``` ```typescript -// src/content/config.ts +// src/content.config.ts import { defineCollection, z } from 'astro:content'; const blog = defineCollection({ @@ -29,7 +29,7 @@ const blog = defineCollection({ title: z.string(), description: z.string(), pubDate: z.coerce.date(), - locale: z.enum(['en', 'fr', 'es']).optional() + locale: z.enum(['en', 'it', 'es']).optional() }) }); @@ -63,9 +63,9 @@ const translations = { nav: { home: 'Home', about: 'About', blog: 'Blog' }, hero: { title: 'Welcome', cta: 'Get Started' } }, - fr: { - nav: { home: 'Accueil', about: 'À propos', blog: 'Blog' }, - hero: { title: 'Bienvenue', cta: 'Commencer' } + es: { + nav: { home: 'Inicio', about: 'Acerca de', blog: 'Blog' }, + hero: { title: 'Bienvenido', cta: 'Empezar' } } } as const; diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/fallback.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/fallback.md index 668c4de..9804a54 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/fallback.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/fallback.md @@ -11,9 +11,9 @@ When a page doesn't exist for a specific locale, Astro can automatically serve t export default defineConfig({ i18n: { defaultLocale: 'en', - locales: ['en', 'fr', 'es', 'pt'], + locales: ['en', 'it', 'es', 'pt'], fallback: { - fr: 'en', // French falls back to English + it: 'en', // Italian falls back to English es: 'en', // Spanish falls back to English pt: 'es' // Portuguese falls back to Spanish } @@ -23,17 +23,17 @@ export default defineConfig({ ## How It Works -If `/fr/new-feature` doesn't exist but `/new-feature` (English) does: +If `/it/new-feature` doesn't exist but `/new-feature` (English) does: -- Astro serves the English content at the `/fr/new-feature` URL +- Astro serves the English content at the `/it/new-feature` URL - No redirect — the URL stays the same - Useful during incremental translation ## Fallback Routing Strategy ```text -Request: /fr/about -→ Check: src/pages/fr/about.astro (missing) +Request: /it/about +→ Check: src/pages/it/about.astro (missing) → Fallback to 'en' → Serve: src/pages/about.astro (found → return English content) ``` diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/helper-functions.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/helper-functions.md index 7279cc4..de44d00 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/helper-functions.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/helper-functions.md @@ -23,12 +23,12 @@ Returns a relative URL for a locale. Respects routing strategy. --- import { getRelativeLocaleUrl } from 'astro:i18n'; -const frAbout = getRelativeLocaleUrl('fr', 'about'); // /fr/about -const frHome = getRelativeLocaleUrl('fr'); // /fr/ +const itAbout = getRelativeLocaleUrl('it', 'about'); // /it/about +const itHome = getRelativeLocaleUrl('it'); // /it/ const enAbout = getRelativeLocaleUrl('en', 'about'); // /about (no prefix) --- -Blog FR +Blog IT ``` ### getAbsoluteLocaleUrl(locale, path?, options?) @@ -36,8 +36,8 @@ const enAbout = getRelativeLocaleUrl('en', 'about'); // /about (no prefix) Returns an absolute URL. Requires `site` configured in `astro.config.mjs`. ```javascript -getAbsoluteLocaleUrl('fr', 'about') -// → https://example.com/fr/about +getAbsoluteLocaleUrl('it', 'about') +// → https://example.com/it/about ``` ### getRelativeLocaleUrlList(path?, options?) @@ -46,7 +46,7 @@ Returns relative URLs for ALL configured locales. ```javascript getRelativeLocaleUrlList('about') -// → ['/about', '/fr/about', '/es/about'] +// → ['/about', '/it/about', '/es/about'] ``` ### getAbsoluteLocaleUrlList(path?, options?) @@ -55,7 +55,7 @@ Returns absolute URLs for ALL configured locales. Used for hreflang generation. ```javascript getAbsoluteLocaleUrlList('about') -// → ['https://example.com/about', 'https://example.com/fr/about'] +// → ['https://example.com/about', 'https://example.com/it/about'] ``` ## Locale Mapping @@ -65,7 +65,7 @@ getAbsoluteLocaleUrlList('about') Returns the URL path segment for a locale. ```javascript -getPathByLocale('fr') // → 'fr' +getPathByLocale('it') // → 'it' ``` ### getLocaleByPath(path) @@ -73,7 +73,7 @@ getPathByLocale('fr') // → 'fr' Returns the locale for a given path segment. ```javascript -getLocaleByPath('fr') // → 'fr' +getLocaleByPath('it') // → 'it' ``` ## Options Parameter @@ -89,7 +89,7 @@ interface GetLocaleOptions { ## Active Link Detection -Unlike some frameworks that strip the locale from the routable path, Astro **keeps the locale prefix** in `Astro.url.pathname` (e.g. `/fr/about`). A naive `pathname === href` comparison breaks active-link highlighting once i18n is added — the helper below strips the locale prefix and the trailing slash before comparing, and treats the locale-root path as an exact match for the home link. +Unlike some frameworks that strip the locale from the routable path, Astro **keeps the locale prefix** in `Astro.url.pathname` (e.g. `/it/about`). A naive `pathname === href` comparison breaks active-link highlighting once i18n is added — the helper below strips the locale prefix and the trailing slash before comparing, and treats the locale-root path as an exact match for the home link. ```typescript // src/utils/isActiveLink.ts @@ -134,7 +134,7 @@ const links = [ import { getAbsoluteLocaleUrlList } from 'astro:i18n'; const currentPath = Astro.url.pathname.replace(/^\/[a-z]{2}(?=\/|$)/, '') || '/'; -const locales = ['en', 'fr', 'es']; +const locales = ['en', 'it', 'es']; --- diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/routing-config.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/routing-config.md index 888a75b..659ad34 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/routing-config.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/routing-config.md @@ -15,9 +15,9 @@ export default defineConfig({ i18n: { defaultLocale: 'en', - locales: ['en', 'fr', 'es', 'de'], + locales: ['en', 'it', 'es', 'de'], routing: { - prefixDefaultLocale: false // /about (en), /fr/about, /es/about + prefixDefaultLocale: false // /about (en), /it/about, /es/about } } }); @@ -31,9 +31,9 @@ With `prefixDefaultLocale: false`: src/pages/ ├── index.astro # / → English (default) ├── about.astro # /about → English -├── fr/ -│ ├── index.astro # /fr/ → French -│ └── about.astro # /fr/about → French +├── it/ +│ ├── index.astro # /it/ → Italian +│ └── about.astro # /it/about → Italian └── es/ ├── index.astro # /es/ → Spanish └── about.astro # /es/about → Spanish @@ -44,7 +44,7 @@ src/pages/ ```astro --- // Available in any .astro page or component -const currentLocale = Astro.currentLocale; // 'en' | 'fr' | 'es' +const currentLocale = Astro.currentLocale; // 'en' | 'it' | 'es' --- @@ -55,9 +55,9 @@ const currentLocale = Astro.currentLocale; // 'en' | 'fr' | 'es' ```javascript i18n: { defaultLocale: 'en', - locales: ['en', 'fr', 'es'], + locales: ['en', 'it', 'es'], fallback: { - fr: 'en', // Missing French pages fall back to English + it: 'en', // Missing Italian pages fall back to English es: 'en' } } diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/sitemap-hreflang.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/sitemap-hreflang.md index 0f3d990..cb3b20c 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/sitemap-hreflang.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/sitemap-hreflang.md @@ -26,7 +26,7 @@ export default defineConfig({ defaultLocale: 'en', locales: { en: 'en-US', // Path key → language attribute - fr: 'fr-FR', + it: 'it-IT', es: 'es-ES', de: 'de-DE' } @@ -36,7 +36,7 @@ export default defineConfig({ i18n: { defaultLocale: 'en', - locales: ['en', 'fr', 'es', 'de'] + locales: ['en', 'it', 'es', 'de'] } }); ``` @@ -47,7 +47,7 @@ export default defineConfig({ https://example.com/about - + @@ -69,7 +69,7 @@ const { path } = Astro.props; const localeMap = { en: 'en-US', - fr: 'fr-FR', + it: 'it-IT', es: 'es-ES' }; diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/strategies.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/strategies.md index b6fffc2..d280745 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/strategies.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/strategies.md @@ -11,8 +11,8 @@ Default locale has no prefix. Other locales are prefixed. ``` / → English (default) /about → English -/fr/ → French -/fr/about → French +/it/ → Italian +/it/about → Italian /es/ → Spanish ``` @@ -27,8 +27,8 @@ All locales have a prefix, including the default. ``` /en/ → English /en/about → English -/fr/ → French -/fr/about → French +/it/ → Italian +/it/about → Italian ``` **Best for:** Sites with equal language weight, or when you want explicit locale in all URLs. @@ -39,7 +39,7 @@ All locales have a prefix, including the default. // prefix-other-locales (default) i18n: { defaultLocale: 'en', - locales: ['en', 'fr', 'es'], + locales: ['en', 'it', 'es'], routing: { prefixDefaultLocale: false } @@ -48,7 +48,7 @@ i18n: { // prefix-always i18n: { defaultLocale: 'en', - locales: ['en', 'fr', 'es'], + locales: ['en', 'it', 'es'], routing: { prefixDefaultLocale: true } @@ -62,11 +62,11 @@ i18n: { ```javascript // With prefixDefaultLocale: false getRelativeLocaleUrl('en', 'about') // → /about -getRelativeLocaleUrl('fr', 'about') // → /fr/about +getRelativeLocaleUrl('it', 'about') // → /it/about // With prefixDefaultLocale: true getRelativeLocaleUrl('en', 'about') // → /en/about -getRelativeLocaleUrl('fr', 'about') // → /fr/about +getRelativeLocaleUrl('it', 'about') // → /it/about ``` ## Choosing a Strategy diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/templates/i18n-config.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/templates/i18n-config.md index 52f097d..7e4632a 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/templates/i18n-config.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/templates/i18n-config.md @@ -17,7 +17,7 @@ export default defineConfig({ defaultLocale: 'en', locales: { en: 'en-US', - fr: 'fr-FR', + it: 'it-IT', es: 'es-ES' } } @@ -26,12 +26,12 @@ export default defineConfig({ i18n: { defaultLocale: 'en', - locales: ['en', 'fr', 'es'], + locales: ['en', 'it', 'es'], routing: { prefixDefaultLocale: false }, fallback: { - fr: 'en', + it: 'en', es: 'en' } } @@ -49,9 +49,9 @@ const translations = { nav: { home: 'Home', about: 'About', blog: 'Blog' }, footer: { copyright: '© 2026 Example. All rights reserved.' } }, - fr: { - nav: { home: 'Accueil', about: 'À propos', blog: 'Blog' }, - footer: { copyright: '© 2026 Example. Tous droits réservés.' } + it: { + nav: { home: 'Home', about: 'Chi siamo', blog: 'Blog' }, + footer: { copyright: '© 2026 Example. Tutti i diritti riservati.' } }, es: { nav: { home: 'Inicio', about: 'Acerca de', blog: 'Blog' }, @@ -72,7 +72,7 @@ export function useTranslations(locale: string): Translations { } ``` -## src/content/config.ts +## src/content.config.ts ```typescript import { defineCollection, z } from 'astro:content'; diff --git a/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/templates/language-switcher.md b/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/templates/language-switcher.md index e5f57eb..b3cb117 100644 --- a/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/templates/language-switcher.md +++ b/.cursor-plugin/plugins/fuse-astro/skills/astro-i18n/references/templates/language-switcher.md @@ -17,12 +17,12 @@ const currentLocale = Astro.currentLocale ?? 'en'; const locales = [ { code: 'en', label: 'English', flag: '🇬🇧' }, - { code: 'fr', label: 'Français', flag: '🇫🇷' }, + { code: 'it', label: 'Italiano', flag: '🇮🇹' }, { code: 'es', label: 'Español', flag: '🇪🇸' } ]; // Strip locale prefix from current path for cross-locale linking -const cleanPath = currentPath.replace(/^\/(en|fr|es)\//, '/'); +const cleanPath = currentPath.replace(/^\/(en|it|es)\//, '/'); ---