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)\//, '/');
---