From bee219c1ad1d9dd2729ac6e7f85c89e96d511944 Mon Sep 17 00:00:00 2001
From: Matthew Phillips
Date: Wed, 27 May 2026 12:13:38 -0400
Subject: [PATCH 01/23] Update v7 upgrade guide: experimental flags,
src/app.ts, @astrojs/db removal
---
src/content/docs/en/guides/upgrade-to/v7.mdx | 68 +++++++++++++++++---
1 file changed, 59 insertions(+), 9 deletions(-)
diff --git a/src/content/docs/en/guides/upgrade-to/v7.mdx b/src/content/docs/en/guides/upgrade-to/v7.mdx
index d4c9be4c68375..910efb5181c4c 100644
--- a/src/content/docs/en/guides/upgrade-to/v7.mdx
+++ b/src/content/docs/en/guides/upgrade-to/v7.mdx
@@ -78,24 +78,74 @@ If you are using Vite-specific plugins, configuration, or APIs, check the [Vite
Most Astro users should be able to upgrade without any changes to their project code. This is primarily a breaking change for Astro integrations and plugins that depend on Vite internals.
-### Rust Compiler
+### Experimental Flags
-The Rust-based Astro compiler, previously available as an experimental flag (`experimental.rustCompiler`), is now the default and only compiler in Astro 7. The Rust compiler delivers significantly faster build times compared to the previous Go-based compiler.
+Experimental flags allow you to opt in to features while they are in early development. The following experimental flags have been removed in Astro 7.0 and are now stable, or the new default behavior.
-##### What should I do?
-
-No action is required for most projects. The Rust compiler is a drop-in replacement for the Go-based compiler.
+Remove these experimental flags from your Astro config if you were previously using them:
-If you had previously opted in to the Rust compiler via the experimental flag, you can now remove it from your configuration:
-
-```js title="astro.config.mjs" del={4-6}
+```js del={5-7} title="astro.config.mjs"
import { defineConfig } from 'astro/config';
export default defineConfig({
experimental: {
rustCompiler: true,
+ advancedRouting: true,
+ routeCaching: true,
},
+})
+```
+
+#### Experimental features now stable:
+
+- `rustCompiler`: The Rust-based Astro compiler is now the default and only compiler, replacing the previous Go-based compiler. No action is required for most projects. If you encounter any issues, please report them on [GitHub](https://github.com/withastro/astro/issues).
+
+- `advancedRouting`: Advanced routing is now enabled by default. See the [advanced routing guide](/en/guides/advanced-routing/) for more information. Note that `src/app.ts` is now a [reserved file name](#reserved-file-name-srcappts).
+
+- `routeCaching`: Route caching is now enabled by default for improved performance.
+
+### Reserved file name: `src/app.ts`
+
+Astro v7.0 introduces [advanced routing](/en/guides/advanced-routing/), which uses `src/app.ts` (or `src/app.js`) as a special file name, similar to `src/middleware.ts`. Astro will automatically import this file to configure routing behavior.
+
+If your project already has a `src/app.ts` file used for other purposes, Astro will attempt to process it as an advanced routing configuration, which may cause unexpected errors.
+
+#### What should I do?
+
+If you have an existing `src/app.ts` file that is not related to advanced routing, you have two options:
+
+**Rename your file** to something else (e.g. `src/application.ts`, `src/main.ts`), and update any imports that reference it.
+
+**Disable advanced routing** by setting `fetchFile: null` in your Astro config:
+
+```js title="astro.config.mjs" ins={4}
+import { defineConfig } from 'astro/config';
+
+export default defineConfig({
+ fetchFile: null,
+});
+```
+
+You can also point `fetchFile` to a different file name if you want to use advanced routing but need to keep `src/app.ts` for another purpose:
+
+```js title="astro.config.mjs" ins={4}
+import { defineConfig } from 'astro/config';
+
+export default defineConfig({
+ fetchFile: './src/router.ts',
});
```
-If you encounter any issues with the Rust compiler, please report them on [GitHub](https://github.com/withastro/astro/issues).
+### Removed: `@astrojs/db`
+
+The `@astrojs/db` package has been removed in Astro v7.0 and is no longer maintained.
+
+#### What should I do?
+
+Remove `@astrojs/db` from your project's dependencies and replace it with one of the following alternatives:
+
+- **Node.js built-in SQLite**: Node.js now includes a built-in [`node:sqlite`](https://nodejs.org/api/sqlite.html) module (available since Node.js v22.5.0). This is a good option if you are using the Node.js adapter and were using `@astrojs/db` for local SQLite storage.
+
+- **[Drizzle ORM](https://orm.drizzle.team/)**: If you were using `@astrojs/db` for its Drizzle-based schema and query API, you can use Drizzle directly with any supported database.
+
+- **Other database libraries**: Use any database library that suits your deployment platform (e.g. [Turso](https://turso.tech/), [PlanetScale](https://planetscale.com/), [Neon](https://neon.tech/)).
From 5ec2ba08c5b7f8854e243ce287d2bea4b2dfa9c3 Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Tue, 2 Jun 2026 16:57:37 +0200
Subject: [PATCH 02/23] remove Astro DB and Advanced Routing from upgrade guide
---
src/content/docs/en/guides/upgrade-to/v7.mdx | 49 --------------------
1 file changed, 49 deletions(-)
diff --git a/src/content/docs/en/guides/upgrade-to/v7.mdx b/src/content/docs/en/guides/upgrade-to/v7.mdx
index 910efb5181c4c..7d8e58e777c4b 100644
--- a/src/content/docs/en/guides/upgrade-to/v7.mdx
+++ b/src/content/docs/en/guides/upgrade-to/v7.mdx
@@ -90,7 +90,6 @@ import { defineConfig } from 'astro/config';
export default defineConfig({
experimental: {
rustCompiler: true,
- advancedRouting: true,
routeCaching: true,
},
})
@@ -100,52 +99,4 @@ export default defineConfig({
- `rustCompiler`: The Rust-based Astro compiler is now the default and only compiler, replacing the previous Go-based compiler. No action is required for most projects. If you encounter any issues, please report them on [GitHub](https://github.com/withastro/astro/issues).
-- `advancedRouting`: Advanced routing is now enabled by default. See the [advanced routing guide](/en/guides/advanced-routing/) for more information. Note that `src/app.ts` is now a [reserved file name](#reserved-file-name-srcappts).
-
- `routeCaching`: Route caching is now enabled by default for improved performance.
-
-### Reserved file name: `src/app.ts`
-
-Astro v7.0 introduces [advanced routing](/en/guides/advanced-routing/), which uses `src/app.ts` (or `src/app.js`) as a special file name, similar to `src/middleware.ts`. Astro will automatically import this file to configure routing behavior.
-
-If your project already has a `src/app.ts` file used for other purposes, Astro will attempt to process it as an advanced routing configuration, which may cause unexpected errors.
-
-#### What should I do?
-
-If you have an existing `src/app.ts` file that is not related to advanced routing, you have two options:
-
-**Rename your file** to something else (e.g. `src/application.ts`, `src/main.ts`), and update any imports that reference it.
-
-**Disable advanced routing** by setting `fetchFile: null` in your Astro config:
-
-```js title="astro.config.mjs" ins={4}
-import { defineConfig } from 'astro/config';
-
-export default defineConfig({
- fetchFile: null,
-});
-```
-
-You can also point `fetchFile` to a different file name if you want to use advanced routing but need to keep `src/app.ts` for another purpose:
-
-```js title="astro.config.mjs" ins={4}
-import { defineConfig } from 'astro/config';
-
-export default defineConfig({
- fetchFile: './src/router.ts',
-});
-```
-
-### Removed: `@astrojs/db`
-
-The `@astrojs/db` package has been removed in Astro v7.0 and is no longer maintained.
-
-#### What should I do?
-
-Remove `@astrojs/db` from your project's dependencies and replace it with one of the following alternatives:
-
-- **Node.js built-in SQLite**: Node.js now includes a built-in [`node:sqlite`](https://nodejs.org/api/sqlite.html) module (available since Node.js v22.5.0). This is a good option if you are using the Node.js adapter and were using `@astrojs/db` for local SQLite storage.
-
-- **[Drizzle ORM](https://orm.drizzle.team/)**: If you were using `@astrojs/db` for its Drizzle-based schema and query API, you can use Drizzle directly with any supported database.
-
-- **Other database libraries**: Use any database library that suits your deployment platform (e.g. [Turso](https://turso.tech/), [PlanetScale](https://planetscale.com/), [Neon](https://neon.tech/)).
From 000454b11713d74986c6ae717d512cd0f3688153 Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Tue, 2 Jun 2026 17:43:24 +0200
Subject: [PATCH 03/23] reorganize the references part
---
astro.sidebar.ts | 1 +
.../docs/en/reference/api-reference.mdx | 54 +++
.../en/reference/cache-provider-reference.mdx | 348 +++++++++++++++
.../experimental-flags/route-caching.mdx | 404 ------------------
4 files changed, 403 insertions(+), 404 deletions(-)
create mode 100644 src/content/docs/en/reference/cache-provider-reference.mdx
diff --git a/astro.sidebar.ts b/astro.sidebar.ts
index 6fb3c17e19646..bd07446068dbe 100644
--- a/astro.sidebar.ts
+++ b/astro.sidebar.ts
@@ -148,6 +148,7 @@ export const sidebar = [
'reference/dev-toolbar-app-reference',
'reference/session-driver-reference',
'reference/font-provider-reference',
+ 'reference/cache-provider-reference',
'reference/container-reference',
'reference/programmatic-reference',
],
diff --git a/src/content/docs/en/reference/api-reference.mdx b/src/content/docs/en/reference/api-reference.mdx
index df1dc39c77d6c..34c0c9e227e10 100644
--- a/src/content/docs/en/reference/api-reference.mdx
+++ b/src/content/docs/en/reference/api-reference.mdx
@@ -1229,3 +1229,57 @@ content="
"
>
```
+
+### `cache`
+
+
+
+
+**Type**: `object | undefined`
+
+
+
+#### `cache.enabled`
+
+
+
+**Type:** `boolean`
+
+
+Whether caching is active. Returns `false` when no cache provider is configured or in development mode. Returns `true` when a cache provider is configured and the app is running in production.
+
+#### `cache.set()`
+
+
+
+**Type:** `(options: CacheOptions | false) => void`
+
+
+Sets cache options for the current request. Pass `false` to opt out of caching.
+
+#### `cache.options`
+
+
+
+**Type:** Readonly\<CacheOptions\>
+
+
+Read-only snapshot of the current accumulated cache options, including all merged `maxAge`, `swr`, `etag`, `lastModified`, and `tags` values.
+
+#### `cache.tags`
+
+
+
+**Type:** `string[]`
+
+
+Read-only array of all accumulated cache tags.
+
+#### `cache.invalidate()`
+
+
+
+**Type:** `(options: InvalidateOptions) => Promise`
+
+
+Purges cached entries. Requires a configured cache provider.
diff --git a/src/content/docs/en/reference/cache-provider-reference.mdx b/src/content/docs/en/reference/cache-provider-reference.mdx
new file mode 100644
index 0000000000000..b31dbdfbe9bd4
--- /dev/null
+++ b/src/content/docs/en/reference/cache-provider-reference.mdx
@@ -0,0 +1,348 @@
+---
+title: Astro Cache Provider API
+sidebar:
+ label: Cache Provider API
+i18nReady: true
+---
+import Since from '~/components/Since.astro';
+import ReadMore from '~/components/ReadMore.astro';
+import { Tabs, TabItem } from '@astrojs/starlight/components';
+
+
+
+
+
+
+## What is a cache provider?
+
+Cache behavior is determined by the configured **cache provider**. Providers fall into two categories:
+
+### CDN providers
+
+CDN providers translate cache directives into response headers (e.g. `CDN-Cache-Control`, `Cache-Tag`) and rely on a CDN or reverse proxy to handle caching. These internal headers are stripped before the response reaches the client.
+
+A CDN provider implements `setHeaders()` to produce the appropriate headers.
+
+### Runtime providers
+
+Runtime providers implement `onRequest()` to intercept requests and cache responses in-process. They add an `X-Astro-Cache` response header for observability:
+
+- **`HIT`**: response served from cache
+- **`MISS`**: response rendered fresh and stored in cache
+- **`STALE`**: stale response served while revalidating in the background
+
+## Built-in memory cache provider
+
+Astro includes a built-in in-memory LRU runtime cache provider suitable for single-instance deployments. Import `memoryCache()` from `astro/config`:
+
+```js title="astro.config.mjs" ins="memoryCache"
+import { defineConfig, memoryCache } from 'astro/config';
+
+export default defineConfig({
+ experimental: {
+ cache: {
+ provider: memoryCache({ max: 500 }),
+ },
+ },
+});
+```
+
+### `memoryCache()` options
+
+
+
+**Type:** `{ max?: number; query?: object }`
+**Default:** `{ max: 1000 }`
+
+
+#### `max`
+
+
+
+**Type:** `number`
+**Default:** `1000`
+
+
+Maximum number of entries to keep in cache. When the cache exceeds this limit, the least recently used entry is evicted.
+
+#### `query`
+
+Controls how query parameters are handled in cache keys.
+
+##### `query.sort`
+
+
+
+**Type:** `boolean`
+**Default:** `true`
+
+
+Sort query parameters alphabetically so that parameter order does not affect the cache key. Set to `false` to disable sorting, and cache URLs with different query parameter order separately. This is useful when parameter order is significant.
+
+##### `query.exclude`
+
+
+
+**Type:** `string[]`
+**Default:** `['utm_*', 'fbclid', 'gclid', 'gbraid', 'wbraid', 'dclid', 'msclkid', 'twclid', 'li_fat_id', 'mc_cid', 'mc_eid', '_ga', '_gl', '_hsenc', '_hsmi', '_ke', 'oly_anon_id', 'oly_enc_id', 'rb_clickid', 's_cid', 'vero_id', 'wickedid', 'yclid', '__s', 'ref']`
+
+
+Exclude query parameters whose names match these patterns from the cache key. Supports glob wildcards (e.g. `"utm_*"`). Cannot be used together with `include`.
+
+By default, common tracking and analytics parameters are excluded. Set to `[]` to include all query parameters in the cache key:
+
+```js title="astro.config.mjs"
+memoryCache({
+ query: { exclude: [] },
+});
+```
+
+##### `query.include`
+
+
+
+**Type:** `string[]`
+
+
+Only include these query parameter names in the cache key. All other parameters are ignored, including the default tracking parameter exclusions. Cannot be used together with `exclude`.
+
+The following example only uses `page` and `sort` parameters in the cache key, ignoring all others:
+
+```js title="astro.config.mjs"
+memoryCache({
+ query: { include: ['page', 'sort'] },
+});
+```
+
+### Cache key behavior
+
+The memory provider automatically normalizes cache keys for better hit rates:
+
+- **Query parameter sorting**: Parameters are sorted alphabetically, so `/page?b=2&a=1` and `/page?a=1&b=2` resolve to the same cache entry.
+- **Tracking parameter exclusion**: Common analytics and tracking parameters (e.g. `utm_source`, `fbclid`, `gclid`) are excluded from the cache key by default. This prevents cache fragmentation from marketing links without affecting your page content.
+- **Vary header support**: When a response includes a [`Vary`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary) header, the memory provider uses the specified request header values to create separate cache entries for each variant. For example, a response with `Vary: Accept-Language` will cache different versions for different languages.
+
+:::note
+The `Cookie` header is always ignored for Vary-based cache keying because it has extremely high cardinality (every user typically has different cookies), making it effectively uncacheable.
+:::
+
+## Writing a custom cache provider
+
+A cache provider has two parts:
+
+1. **The runtime module** — A file that **default-exports** a `CacheProviderFactory` function. This module is bundled into your SSR output, so it must be runtime-agnostic: avoid Node.js built-in modules (e.g. `node:fs`, `node:path`) unless your target runtime supports them.
+
+2. **The config helper** — A function exported for users to call in `astro.config.mjs`. It returns a [`CacheProviderConfig` object](#cacheproviderconfig) that tells Astro where to find the runtime module and what options to pass it. This is the same pattern used by `memoryCache()` from `astro/config`.
+
+The following example shows a config helper that accepts typed options and points to a runtime module:
+
+```ts title="my-provider/config.ts"
+import type { CacheProviderConfig } from 'astro';
+
+interface MyProviderOptions {
+ apiKey: string;
+ region?: string;
+}
+
+export function myCache(options: MyProviderOptions): CacheProviderConfig {
+ return {
+ entrypoint: 'my-provider/runtime', // resolved from the project root
+ config: options, // passed to the factory at runtime
+ };
+}
+```
+
+The config helper is then called in the Astro config:
+
+```js title="astro.config.mjs"
+import { defineConfig } from 'astro/config';
+import { myCache } from 'my-provider/config';
+
+export default defineConfig({
+ experimental: {
+ cache: {
+ provider: myCache({ apiKey: '...' }),
+ },
+ },
+});
+```
+
+The runtime module default-exports a factory that receives the serialized `config` and returns a [`CacheProvider`](#cacheprovider-interface):
+
+```ts title="my-provider/runtime.ts"
+import type { CacheProviderFactory } from 'astro';
+
+const factory: CacheProviderFactory = (config) => {
+ return {
+ name: 'my-cache-provider',
+
+ // CDN-style: translate cache options into response headers
+ setHeaders(options) {
+ const headers = new Headers();
+ if (options.maxAge !== undefined) {
+ let value = `max-age=${options.maxAge}`;
+ if (options.swr !== undefined) {
+ value += `, stale-while-revalidate=${options.swr}`;
+ }
+ headers.set('CDN-Cache-Control', value);
+ }
+ if (options.tags?.length) {
+ headers.set('Cache-Tag', options.tags.join(','));
+ }
+ return headers;
+ },
+
+ // Runtime-style: intercept requests (optional)
+ async onRequest(context, next) {
+ // Check cache, call next(), store response...
+ return next();
+ },
+
+ // Handle invalidation requests
+ async invalidate(options) {
+ // Purge by tags or path...
+ },
+ };
+};
+
+export default factory;
+```
+
+## Cache provider types reference
+
+The following types can be imported from the `astro` module:
+
+```ts
+import type {
+ CacheOptions,
+ CacheProvider,
+ CacheProviderConfig,
+ CacheProviderFactory,
+ InvalidateOptions,
+} from "astro";
+```
+
+### `CacheOptions`
+
+#### `maxAge`
+
+
+
+**Type:** `number`
+
+
+Time in seconds the response is considered fresh.
+
+#### `swr`
+
+
+
+**Type:** `number`
+
+
+Stale-while-revalidate window in seconds. Stale content is served while a fresh response is generated in the background.
+
+#### `tags`
+
+
+
+**Type:** `string[]`
+
+
+Cache tags for targeted invalidation. Tags accumulate across multiple `set()` calls.
+
+#### `lastModified`
+
+
+
+**Type:** `Date`
+
+
+When multiple `set()` calls provide `lastModified`, the most recent date wins.
+
+#### `etag`
+
+
+
+**Type:** `string`
+
+
+Entity tag for conditional requests.
+
+### `CacheProvider`
+
+Describes a provider used for caching. This requires the `name` and `invalidate()` properties and accepts optional properties.
+
+#### `name`
+
+
+
+**Type:** `string`
+
+
+A unique name for the provider, used in logs and for identification.
+
+#### `setHeaders()`
+
+
+
+**Type:** `(options: CacheOptions) => Headers`
+
+
+Translates cache options into response headers. Called after the response is rendered but before it is sent to the client. These headers are stripped from the final response.
+
+#### `onRequest()`
+
+
+
+**Type:** `(context: { request: Request; url: URL; waitUntil?: (promise: Promise) => void }, next: MiddlewareNext) => Promise`
+
+
+Intercepts requests to implement runtime caching. The `context` includes a `waitUntil` function (when available in the runtime) for background work such as stale-while-revalidate.
+
+#### `invalidate()`
+
+
+
+**Type:** `(options: InvalidateOptions) => Promise`
+
+
+Handles purge requests by tag or path.
+
+### `CacheProviderConfig`
+
+
+
+**Type:** `{ entrypoint: string | URL; config?: Record }`
+
+
+The configuration object passed to `experimental.cache.provider`. Use a helper function (e.g. `memoryCache()`) for type-safe configuration.
+
+### `CacheProviderFactory`
+
+
+
+**Type:** `(config: Record | undefined) => CacheProvider`
+
+
+The factory function type. Receives the provider's serializable config object from the Astro config.
+
+### `InvalidateOptions`
+
+#### `path`
+
+
+
+**Type:** `string`
+
+
+Exact path to invalidate. No glob or wildcard support.
+
+#### `tags`
+
+
+
+**Type:** `string | string[]`
+
+
+Tag or tags to invalidate. All entries with matching tags are purged.
diff --git a/src/content/docs/en/reference/experimental-flags/route-caching.mdx b/src/content/docs/en/reference/experimental-flags/route-caching.mdx
index 706867ae0a1df..17271610038af 100644
--- a/src/content/docs/en/reference/experimental-flags/route-caching.mdx
+++ b/src/content/docs/en/reference/experimental-flags/route-caching.mdx
@@ -290,407 +290,3 @@ Patterns use the same matching and priority rules as Astro's [file-based routing
### Merging with per-route `cache.set()`
Per-route `cache.set()` calls merge with config-level route rules. Route code can override or extend the defaults set in config.
-
-## Cache providers
-
-Cache behavior is determined by the configured **cache provider**. Providers fall into two categories:
-
-### CDN providers
-
-CDN providers translate cache directives into response headers (e.g. `CDN-Cache-Control`, `Cache-Tag`) and rely on a CDN or reverse proxy to handle caching. These internal headers are stripped before the response reaches the client.
-
-A CDN provider implements `setHeaders()` to produce the appropriate headers.
-
-### Runtime providers
-
-Runtime providers implement `onRequest()` to intercept requests and cache responses in-process. They add an `X-Astro-Cache` response header for observability:
-
-- **`HIT`**: response served from cache
-- **`MISS`**: response rendered fresh and stored in cache
-- **`STALE`**: stale response served while revalidating in the background
-
-### Built-in memory cache provider
-
-Astro includes a built-in in-memory LRU runtime cache provider suitable for single-instance deployments. Import `memoryCache` from `astro/config`:
-
-```js title="astro.config.mjs" ins="memoryCache"
-import { defineConfig, memoryCache } from 'astro/config';
-
-export default defineConfig({
- experimental: {
- cache: {
- provider: memoryCache({ max: 500 }),
- },
- },
-});
-```
-
-#### Cache key behavior
-
-The memory provider automatically normalizes cache keys for better hit rates:
-
-- **Query parameter sorting**: Parameters are sorted alphabetically, so `/page?b=2&a=1` and `/page?a=1&b=2` resolve to the same cache entry.
-- **Tracking parameter exclusion**: Common analytics and tracking parameters (e.g. `utm_source`, `fbclid`, `gclid`) are excluded from the cache key by default. This prevents cache fragmentation from marketing links without affecting your page content.
-- **Vary header support**: When a response includes a [`Vary`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary) header, the memory provider uses the specified request header values to create separate cache entries for each variant. For example, a response with `Vary: Accept-Language` will cache different versions for different languages.
-
-:::note
-The `Cookie` header is always ignored for Vary-based cache keying because it has extremely high cardinality (every user typically has different cookies), making it effectively uncacheable.
-:::
-
-#### `memoryCache()` options
-
-
-
-**Type:** `{ max?: number; query?: object }`
-**Default:** `{ max: 1000 }`
-
-
-
-##### `max`
-
-
-
-**Type:** `number`
-**Default:** `1000`
-
-
-
-Maximum number of entries to keep in cache. When the cache exceeds this limit, the least recently used entry is evicted.
-
-##### `query`
-
-Controls how query parameters are handled in cache keys.
-
-###### `query.sort`
-
-
-
-**Type:** `boolean`
-**Default:** `true`
-
-
-
-Sort query parameters alphabetically so that parameter order does not affect the cache key. Set to `false` to disable sorting, and cache URLs with different query parameter order separately. This is useful when parameter order is significant.
-
-###### `query.exclude`
-
-
-
-**Type:** `string[]`
-**Default:** `['utm_*', 'fbclid', 'gclid', 'gbraid', 'wbraid', 'dclid', 'msclkid', 'twclid', 'li_fat_id', 'mc_cid', 'mc_eid', '_ga', '_gl', '_hsenc', '_hsmi', '_ke', 'oly_anon_id', 'oly_enc_id', 'rb_clickid', 's_cid', 'vero_id', 'wickedid', 'yclid', '__s', 'ref']`
-
-
-
-Exclude query parameters whose names match these patterns from the cache key. Supports glob wildcards (e.g. `"utm_*"`). Cannot be used together with `include`.
-
-By default, common tracking and analytics parameters are excluded. Set to `[]` to include all query parameters in the cache key:
-
-```js title="astro.config.mjs"
-memoryCache({
- query: { exclude: [] },
-});
-```
-
-###### `query.include`
-
-
-
-**Type:** `string[]`
-
-
-
-Only include these query parameter names in the cache key. All other parameters are ignored, including the default tracking parameter exclusions. Cannot be used together with `exclude`.
-
-The following example only uses `page` and `sort` parameters in the cache key, ignoring all others:
-
-```js title="astro.config.mjs"
-memoryCache({
- query: { include: ['page', 'sort'] },
-});
-```
-
-## Writing a custom cache provider
-
-A cache provider has two parts:
-
-1. **The runtime module** — A file that **default-exports** a `CacheProviderFactory` function. This module is bundled into your SSR output, so it must be runtime-agnostic: avoid Node.js built-in modules (e.g. `node:fs`, `node:path`) unless your target runtime supports them.
-
-2. **The config helper** — A function exported for users to call in `astro.config.mjs`. It returns a [`CacheProviderConfig` object](#cacheproviderconfig) that tells Astro where to find the runtime module and what options to pass it. This is the same pattern used by `memoryCache()` from `astro/config`.
-
-The following example shows a config helper that accepts typed options and points to a runtime module:
-
-```ts title="my-provider/config.ts"
-import type { CacheProviderConfig } from 'astro';
-
-interface MyProviderOptions {
- apiKey: string;
- region?: string;
-}
-
-export function myCache(options: MyProviderOptions): CacheProviderConfig {
- return {
- entrypoint: 'my-provider/runtime', // resolved from the project root
- config: options, // passed to the factory at runtime
- };
-}
-```
-
-The config helper is then called in the Astro config:
-
-```js title="astro.config.mjs"
-import { defineConfig } from 'astro/config';
-import { myCache } from 'my-provider/config';
-
-export default defineConfig({
- experimental: {
- cache: {
- provider: myCache({ apiKey: '...' }),
- },
- },
-});
-```
-
-The runtime module default-exports a factory that receives the serialized `config` and returns a [`CacheProvider`](#cacheprovider-interface):
-
-```ts title="my-provider/runtime.ts"
-import type { CacheProviderFactory } from 'astro';
-
-const factory: CacheProviderFactory = (config) => {
- return {
- name: 'my-cache-provider',
-
- // CDN-style: translate cache options into response headers
- setHeaders(options) {
- const headers = new Headers();
- if (options.maxAge !== undefined) {
- let value = `max-age=${options.maxAge}`;
- if (options.swr !== undefined) {
- value += `, stale-while-revalidate=${options.swr}`;
- }
- headers.set('CDN-Cache-Control', value);
- }
- if (options.tags?.length) {
- headers.set('Cache-Tag', options.tags.join(','));
- }
- return headers;
- },
-
- // Runtime-style: intercept requests (optional)
- async onRequest(context, next) {
- // Check cache, call next(), store response...
- return next();
- },
-
- // Handle invalidation requests
- async invalidate(options) {
- // Purge by tags or path...
- },
- };
-};
-
-export default factory;
-```
-
-### `CacheProvider` interface
-
-Describes a provider used for caching. This requires the `name` and `invalidate()` properties and accepts optional properties.
-
-#### `name`
-
-
-
-**Type:** `string`
-
-
-
-A unique name for the provider, used in logs and for identification.
-
-#### `setHeaders()`
-
-
-
-**Type:** `(options: CacheOptions) => Headers`
-
-
-
-Translates cache options into response headers. Called after the response is rendered but before it is sent to the client. These headers are stripped from the final response.
-
-#### `onRequest()`
-
-
-
-**Type:** `(context: { request: Request; url: URL; waitUntil?: (promise: Promise) => void }, next: MiddlewareNext) => Promise`
-
-
-
-Intercepts requests to implement runtime caching. The `context` includes a `waitUntil` function (when available in the runtime) for background work such as stale-while-revalidate.
-
-#### `invalidate()`
-
-
-
-**Type:** `(options: InvalidateOptions) => Promise`
-
-
-
-Handles purge requests by tag or path.
-
-### `CacheProviderFactory`
-
-
-
-**Type:** `(config: Record | undefined) => CacheProvider`
-
-
-
-The factory function type. Receives the provider's serializable config object from the Astro config.
-
-## API reference
-
-### `cache.enabled`
-
-
-
-**Type:** `boolean`
-
-
-
-Whether caching is active. Returns `false` when no cache provider is configured or in development mode. Returns `true` when a cache provider is configured and the app is running in production.
-
-### `cache.set()`
-
-
-
-**Type:** `(options: CacheOptions | false) => void`
-
-
-
-Sets cache options for the current request. Pass `false` to opt out of caching.
-
-#### `CacheOptions`
-
-##### `maxAge`
-
-
-
-**Type:** `number`
-
-
-
-Time in seconds the response is considered fresh.
-
-##### `swr`
-
-
-
-**Type:** `number`
-
-
-
-Stale-while-revalidate window in seconds. Stale content is served while a fresh response is generated in the background.
-
-##### `tags`
-
-
-
-**Type:** `string[]`
-
-
-
-Cache tags for targeted invalidation. Tags accumulate across multiple `set()` calls.
-
-##### `lastModified`
-
-
-
-**Type:** `Date`
-
-
-
-When multiple `set()` calls provide `lastModified`, the most recent date wins.
-
-##### `etag`
-
-
-
-**Type:** `string`
-
-
-
-Entity tag for conditional requests.
-
-### `cache.options`
-
-
-
-**Type:** Readonly\<CacheOptions\>
-
-
-
-Read-only snapshot of the current accumulated cache options, including all merged `maxAge`, `swr`, `etag`, `lastModified`, and `tags` values.
-
-### `cache.tags`
-
-
-
-**Type:** `string[]`
-
-
-
-Read-only array of all accumulated cache tags.
-
-### `cache.invalidate()`
-
-
-
-**Type:** `(options: InvalidateOptions) => Promise`
-
-
-
-Purges cached entries. Requires a configured cache provider.
-
-#### `InvalidateOptions`
-
-##### `path`
-
-
-
-**Type:** `string`
-
-
-
-Exact path to invalidate. No glob or wildcard support.
-
-##### `tags`
-
-
-
-**Type:** `string | string[]`
-
-
-
-Tag or tags to invalidate. All entries with matching tags are purged.
-
-### `CacheProviderConfig`
-
-
-
-**Type:** `{ entrypoint: string | URL; config?: Record }`
-
-
-
-The configuration object passed to `experimental.cache.provider`. Use a helper function (e.g. `memoryCache()`) for type-safe configuration.
-
-## Error handling
-
-### `CacheNotEnabled`
-
-Thrown when `cache.invalidate()` is called without a configured cache provider. Other cache methods (`set()`, `tags`, `options`) no-op when caching is not configured, logging a one-time warning on the first `set()` call.
-
-### `CacheProviderNotFound`
-
-Thrown at build time when the configured cache provider cannot be resolved. This typically means the package is not installed or the import path is incorrect.
-
-## Further reading
-
-For full details and to give feedback on this experimental API, see the [Route Caching RFC](https://github.com/withastro/roadmap/pull/1245).
From 7e8756b8ae4277e8e8b8738f8b2d055e188ce210 Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Tue, 2 Jun 2026 18:16:00 +0200
Subject: [PATCH 04/23] reorganize the guide parts
---
.../docs/en/guides/content-collections.mdx | 101 +++++++
src/content/docs/en/guides/routing.mdx | 159 ++++++++++
.../experimental-flags/route-caching.mdx | 280 ------------------
3 files changed, 260 insertions(+), 280 deletions(-)
diff --git a/src/content/docs/en/guides/content-collections.mdx b/src/content/docs/en/guides/content-collections.mdx
index 4d8bdc19ad392..cb95424e2bae9 100644
--- a/src/content/docs/en/guides/content-collections.mdx
+++ b/src/content/docs/en/guides/content-collections.mdx
@@ -868,6 +868,107 @@ if (error) {
---
```
+### Caching live data
+
+
+
+[Route caching](/en/guides/routing/#route-caching) integrates directly with live content collections. `cache.set()` accepts `CacheHint` and `LiveDataEntry` objects natively, allowing cache hints from loaders to be passed through without manually setting headers.
+
+A [live loader](/en/reference/content-loader-reference/#live-loaders) can return a `cacheHint` on individual entries or on the collection as a whole. These hints include `tags` (for targeted invalidation) and `lastModified` (for freshness). When passed to `cache.set()`, they merge with any other cache options already set on the page.
+
+#### Passing cache hints from entries
+
+Pass the `cacheHint` returned by `getLiveEntry()` or `getLiveCollection()` directly to `cache.set()`.
+
+The following example passes the loader's cache hint and adds a `maxAge` to control how long the response stays fresh:
+
+```astro title="src/pages/products/[id].astro"
+---
+import { getLiveEntry } from 'astro:content';
+
+const { entry, error, cacheHint } = await getLiveEntry('products', Astro.params.id);
+
+if (error) {
+ return Astro.redirect('/404');
+}
+
+if (cacheHint) {
+ Astro.cache.set(cacheHint);
+}
+Astro.cache.set({ maxAge: 300 });
+---
+
+{entry.data.name}
+```
+
+A [`LiveDataEntry`](/en/reference/content-loader-reference/#livedataentry) can also be passed directly. Astro extracts its `cacheHint` automatically:
+
+```astro title="src/pages/products/[id].astro"
+---
+import { getLiveEntry } from 'astro:content';
+
+const { entry, error } = await getLiveEntry('products', Astro.params.id);
+
+if (error) {
+ return Astro.redirect('/404');
+}
+
+Astro.cache.set(entry);
+Astro.cache.set({ maxAge: 300, swr: 60 });
+---
+
+{entry.data.name}
+```
+
+#### Invalidating by entry
+
+`cache.invalidate()` also accepts a `LiveDataEntry`, invalidating all cached responses tagged with that entry's cache tags.
+
+The following example invalidates the cached response for a specific product entry:
+
+```ts title="src/pages/api/revalidate.ts"
+import { getLiveEntry } from 'astro:content';
+
+export async function POST(context) {
+ const { entry } = await getLiveEntry('products', 'featured');
+ if (entry) {
+ await context.cache.invalidate(entry);
+ }
+ return Response.json({ ok: true });
+}
+```
+
+#### Collection-level cache hints
+
+When fetching a full collection with `getLiveCollection()`, Astro merges cache hints from the collection response and all individual entries: tags are accumulated, and the most recent `lastModified` wins.
+
+The following example passes the merged cache hint from a collection and sets a 10-minute freshness window:
+
+```astro title="src/pages/products/index.astro"
+---
+import { getLiveCollection } from 'astro:content';
+
+const { entries, error, cacheHint } = await getLiveCollection('products');
+
+if (error) {
+ return new Response('Error loading products', { status: 500 });
+}
+
+if (cacheHint) {
+ Astro.cache.set(cacheHint);
+}
+Astro.cache.set({ maxAge: 600 });
+---
+
+
+ {entries.map((p) => - {p.data.name}
)}
+
+```
+
+
+See the [Content Loader Reference](/en/reference/content-loader-reference/) for more about implementing cache hints in your live loaders.
+
+
## Using JSON Schema files in your editor
diff --git a/src/content/docs/en/guides/routing.mdx b/src/content/docs/en/guides/routing.mdx
index 30e5a801b2913..72793e1cec615 100644
--- a/src/content/docs/en/guides/routing.mdx
+++ b/src/content/docs/en/guides/routing.mdx
@@ -575,3 +575,162 @@ In this example, only `src/pages/index.astro` and `src/pages/projects/project1.m
- _utils.js
- **project1.md**
+
+## Route caching
+
+
+
+Route caching is a platform-agnostic API for caching responses from [on-demand rendered](/en/guides/on-demand-rendering/) pages and endpoints. Cache directives set in your routes are translated into the appropriate headers or runtime behavior depending on your configured cache provider.
+
+Route caching builds on standard [HTTP caching semantics](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching), including `max-age` and [`stale-while-revalidate`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-while-revalidate), with support for tag-based and path-based invalidation, config-level route rules, and pluggable cache providers that adapters can set automatically.
+
+To enable this feature, set a [cache provider](/en/reference/cache-provider-reference/) in your Astro config:
+
+```js title="astro.config.mjs" {6-8} "memoryCache"
+import { defineConfig, memoryCache } from 'astro/config';
+import node from '@astrojs/node';
+
+export default defineConfig({
+ adapter: node({ mode: 'standalone' }),
+ cache: {
+ provider: memoryCache(),
+ },
+});
+```
+
+You can then use [`Astro.cache`](/en/reference/api-reference/#cache) in your `.astro` pages (or `context.cache` for endpoints and middleware) to control caching per request. Cache defaults for groups of routes can also be defined declaratively in your config using [`routeRules`](#route-rules).
+
+### Checking if caching is enabled
+
+Use `cache.enabled` to check whether a cache provider is configured and active. This returns `false` when no provider is configured, or in development mode:
+
+```astro title="src/pages/products/[id].astro" "Astro.cache.enabled"
+---
+if (Astro.cache.enabled) {
+ const tags = await getProductTags(Astro.params.id);
+ Astro.cache.set({ maxAge: 3600, tags });
+}
+---
+```
+
+When caching is not enabled, `cache.set()`, `cache.tags`, and `cache.options` will log a warning, and `cache.invalidate()` will throw an error. Use `cache.enabled` to check before calling these methods.
+
+### Setting cache options
+
+Call `cache.set()` with an options object to enable caching for the current response.
+
+The following example caches a page for 2 minutes, serves stale content for 1 minute while revalidating, and tags the response for targeted invalidation:
+
+```astro title="src/pages/index.astro" ins={4-8}
+---
+export const prerender = false; // Not needed in 'server' mode
+
+Astro.cache.set({
+ maxAge: 120,
+ swr: 60,
+ tags: ['home'],
+});
+---
+
+Cached page
+```
+
+In API routes and middleware, use `context.cache`:
+
+```ts title="src/pages/api/data.ts" ins={2-5}
+export function GET(context) {
+ context.cache.set({
+ maxAge: 300,
+ tags: ['api', 'data'],
+ });
+ return Response.json({ ok: true });
+}
+```
+
+### Opting out of caching
+
+Call `cache.set(false)` to explicitly opt a request out of caching. This is useful when a matched [route rule](#route-rules) would otherwise cache the response:
+
+```astro title="src/pages/dashboard.astro"
+---
+if (isPersonalized) {
+ Astro.cache.set(false);
+}
+---
+```
+
+### Reading cache state
+
+Access the current accumulated cache options via `cache.options`:
+
+```ts title="src/pages/api/debug.ts"
+const { maxAge, swr, tags } = context.cache.options;
+```
+
+### Invalidating cache entries
+
+Purge cached entries by tag or path using `cache.invalidate()`.
+
+The following example creates an API route that invalidates by tag and by path:
+
+```ts title="src/pages/api/revalidate.ts"
+export async function POST(context) {
+ // Invalidate all entries tagged 'data'
+ await context.cache.invalidate({ tags: ['data'] });
+
+ // Invalidate a specific path
+ await context.cache.invalidate({ path: '/api/data' });
+
+ return Response.json({ purged: true });
+}
+```
+
+Tag-based invalidation removes all cached entries whose tags include any of the provided tags. Path-based invalidation is exact-match only (no [glob](/en/guides/imports/#glob-patterns) or wildcard patterns).
+
+### Merge behavior
+
+Multiple calls to `cache.set()` within a single request are merged:
+
+- **Scalar values** (`maxAge`, `swr`, `etag`): last-write-wins
+- **`lastModified`**: most recent date wins
+- **`tags`**: accumulate across all calls
+
+Middleware, layouts, content loaders, and page code can each contribute cache directives independently.
+
+### Dev mode behavior
+
+In dev mode, the cache API is available so that route code does not need conditional checks, but no actual caching occurs. `cache.enabled` is `false`, and `cache.set()` and `cache.invalidate()` are no-ops. To test your caching locally, build then preview your site.
+
+### Route rules
+
+Route rules allow you to define caching behavior for groups of routes declaratively in your config. This is useful for applying caching to large groups of routes at once.
+
+The following example caches all API routes with stale-while-revalidate, product pages with a 1-hour freshness window, and blog posts for 5 minutes:
+
+```js title="astro.config.mjs" {9-13}
+import { defineConfig, memoryCache } from 'astro/config';
+import node from '@astrojs/node';
+
+export default defineConfig({
+ adapter: node({ mode: 'standalone' }),
+ cache: {
+ provider: memoryCache(),
+ },
+ routeRules: {
+ '/api/*': { swr: 600 },
+ '/products/*': { maxAge: 3600, tags: ['products'] },
+ '/blog/[...slug]': { maxAge: 300, swr: 60 },
+ },
+});
+```
+
+The following route patterns are supported:
+
+- **Static paths**: `/about`, `/api/health`
+- **Dynamic parameters**: `/products/[id]`, `/blog/[slug]`
+- **Rest parameters**: `/docs/[...path]`
+- **Glob wildcards**: `/api/*`
+
+Patterns use the same matching and priority rules as Astro's [file-based routing](#route-priority-order), so more specific patterns take precedence.
+
+Per-route `cache.set()` calls merge with config-level route rules. Route code can override or extend the defaults set in config. For example, a route rule might set a default `maxAge` for all product pages, but individual pages can call `cache.set()` to customize or disable caching as needed.
diff --git a/src/content/docs/en/reference/experimental-flags/route-caching.mdx b/src/content/docs/en/reference/experimental-flags/route-caching.mdx
index 17271610038af..771552b3fd6f7 100644
--- a/src/content/docs/en/reference/experimental-flags/route-caching.mdx
+++ b/src/content/docs/en/reference/experimental-flags/route-caching.mdx
@@ -10,283 +10,3 @@ tableOfContents:
import Since from '~/components/Since.astro';
import ReadMore from '~/components/ReadMore.astro';
-
-
-
-**Type:** `object`
-**Default:** `undefined`
-
-
-
-
-Enables a platform-agnostic API for caching responses from [on-demand rendered](/en/guides/on-demand-rendering/) pages and endpoints. Cache directives set in your routes are translated into the appropriate headers or runtime behavior depending on your configured cache provider.
-
-Route caching builds on standard [HTTP caching semantics](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching), including `max-age` and [`stale-while-revalidate`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-while-revalidate), with support for tag-based and path-based invalidation, config-level route rules, and pluggable cache providers that adapters can set automatically.
-
-This feature requires [on-demand rendering](/en/guides/on-demand-rendering/). Prerendered pages are already static and do not use route caching.
-
-To enable this feature, configure `experimental.cache` with a cache provider in your Astro config:
-
-```js title="astro.config.mjs" {2,5} ins="memoryCache"
-import { defineConfig, memoryCache } from 'astro/config';
-import node from '@astrojs/node';
-
-export default defineConfig({
- adapter: node({ mode: 'standalone' }),
- experimental: {
- cache: {
- provider: memoryCache(),
- },
- },
-});
-```
-
-## Using route caching
-
-Use `Astro.cache` in `.astro` pages or `context.cache` in API routes and middleware to control caching per request. Cache defaults for groups of routes can also be defined declaratively in your config using [`experimental.routeRules`](#route-rules).
-
-### Checking if caching is enabled
-
-Use `cache.enabled` to check whether a cache provider is configured and active. This returns `false` when no provider is configured, or in development mode:
-
-```astro title="src/pages/products/[id].astro" "Astro.cache.enabled"
----
-if (Astro.cache.enabled) {
- const tags = await getProductTags(Astro.params.id);
- Astro.cache.set({ maxAge: 3600, tags });
-}
----
-```
-
-When caching is not enabled, `cache.set()`, `cache.tags`, and `cache.options` will log a warning, and `cache.invalidate()` will throw an error. Use `cache.enabled` to check before calling these methods.
-
-### Setting cache options
-
-Call `cache.set()` with an options object to enable caching for the current response.
-
-The following example caches a page for 2 minutes, serves stale content for 1 minute while revalidating, and tags the response for targeted invalidation:
-
-```astro title="src/pages/index.astro" ins={4-8}
----
-export const prerender = false; // Not needed in 'server' mode
-
-Astro.cache.set({
- maxAge: 120,
- swr: 60,
- tags: ['home'],
-});
----
-
-Cached page
-```
-
-In API routes and middleware, use `context.cache`:
-
-```ts title="src/pages/api/data.ts" ins={2-5}
-export function GET(context) {
- context.cache.set({
- maxAge: 300,
- tags: ['api', 'data'],
- });
- return Response.json({ ok: true });
-}
-```
-
-### Opting out of caching
-
-Call `cache.set(false)` to explicitly opt a request out of caching. This is useful when a matched [route rule](#route-rules) would otherwise cache the response:
-
-```astro title="src/pages/dashboard.astro"
----
-if (isPersonalized) {
- Astro.cache.set(false);
-}
----
-```
-
-### Reading cache state
-
-Access the current accumulated cache options via `cache.options`:
-
-```ts title="src/pages/api/debug.ts"
-const { maxAge, swr, tags } = context.cache.options;
-```
-
-### Merge behavior
-
-Multiple calls to `cache.set()` within a single request are merged:
-
-- **Scalar values** (`maxAge`, `swr`, `etag`): last-write-wins
-- **`lastModified`**: most recent date wins
-- **`tags`**: accumulate across all calls
-
-Middleware, layouts, content loaders, and page code can each contribute cache directives independently.
-
-### Dev mode behavior
-
-In dev mode, the cache API is available so that route code does not need conditional checks, but no actual caching occurs. `cache.enabled` is `false`, and `cache.set()` and `cache.invalidate()` are no-ops. To test your caching locally, build then preview your site.
-
-## Using with live content collections
-
-Route caching integrates directly with [live content collections](/en/guides/content-collections/#live-content-collections). `cache.set()` accepts `CacheHint` and `LiveDataEntry` objects natively, allowing cache hints from loaders to be passed through without manually setting headers.
-
-A [live loader](/en/reference/content-loader-reference/#live-loaders) can return a `cacheHint` on individual entries or on the collection as a whole. These hints include `tags` (for targeted invalidation) and `lastModified` (for freshness). When passed to `cache.set()`, they merge with any other cache options already set on the page.
-
-### Passing cache hints from entries
-
-Pass the `cacheHint` returned by `getLiveEntry()` or `getLiveCollection()` directly to `cache.set()`.
-
-The following example passes the loader's cache hint and adds a `maxAge` to control how long the response stays fresh:
-
-```astro title="src/pages/products/[id].astro"
----
-import { getLiveEntry } from 'astro:content';
-
-const { entry, error, cacheHint } = await getLiveEntry('products', Astro.params.id);
-
-if (error) {
- return Astro.redirect('/404');
-}
-
-if (cacheHint) {
- Astro.cache.set(cacheHint);
-}
-Astro.cache.set({ maxAge: 300 });
----
-
-{entry.data.name}
-```
-
-A [`LiveDataEntry`](/en/reference/content-loader-reference/#livedataentry) can also be passed directly. Astro extracts its `cacheHint` automatically:
-
-```astro title="src/pages/products/[id].astro"
----
-import { getLiveEntry } from 'astro:content';
-
-const { entry, error } = await getLiveEntry('products', Astro.params.id);
-
-if (error) {
- return Astro.redirect('/404');
-}
-
-Astro.cache.set(entry);
-Astro.cache.set({ maxAge: 300, swr: 60 });
----
-
-{entry.data.name}
-```
-
-### Invalidating by entry
-
-`cache.invalidate()` also accepts a `LiveDataEntry`, invalidating all cached responses tagged with that entry's cache tags.
-
-The following example invalidates the cached response for a specific product entry:
-
-```ts title="src/pages/api/revalidate.ts"
-import { getLiveEntry } from 'astro:content';
-
-export async function POST(context) {
- const { entry } = await getLiveEntry('products', 'featured');
- if (entry) {
- await context.cache.invalidate(entry);
- }
- return Response.json({ ok: true });
-}
-```
-
-### Collection-level cache hints
-
-When fetching a full collection with `getLiveCollection()`, Astro merges cache hints from the collection response and all individual entries: tags are accumulated, and the most recent `lastModified` wins.
-
-The following example passes the merged cache hint from a collection and sets a 10-minute freshness window:
-
-```astro title="src/pages/products/index.astro"
----
-import { getLiveCollection } from 'astro:content';
-
-const { entries, error, cacheHint } = await getLiveCollection('products');
-
-if (error) {
- return new Response('Error loading products', { status: 500 });
-}
-
-if (cacheHint) {
- Astro.cache.set(cacheHint);
-}
-Astro.cache.set({ maxAge: 600 });
----
-
-
- {entries.map((p) => - {p.data.name}
)}
-
-```
-
-
- See the [Content Loader Reference](/en/reference/content-loader-reference/) for more about
- implementing cache hints in your live loaders.
-
-
-## Invalidation
-
-Purge cached entries by tag or path using `cache.invalidate()`.
-
-The following example creates an API route that invalidates by tag and by path:
-
-```ts title="src/pages/api/revalidate.ts"
-export async function POST(context) {
- // Invalidate all entries tagged 'data'
- await context.cache.invalidate({ tags: ['data'] });
-
- // Invalidate a specific path
- await context.cache.invalidate({ path: '/api/data' });
-
- return Response.json({ purged: true });
-}
-```
-
-Tag-based invalidation removes all cached entries whose tags include any of the provided tags. Path-based invalidation is exact-match only (no [glob](/en/guides/imports/#glob-patterns) or wildcard patterns).
-
-## Route rules
-
-
-
-**Type:** `Record`
-**Default:** `undefined`
-
-
-
-`experimental.routeRules` sets default cache options for routes declaratively in your config, without modifying route code. This is useful for applying caching to large groups of routes at once.
-
-The following example caches all API routes with stale-while-revalidate, product pages with a 1-hour freshness window, and blog posts for 5 minutes:
-
-```js title="astro.config.mjs" ins={8-12}
-import { defineConfig, memoryCache } from 'astro/config';
-
-export default defineConfig({
- experimental: {
- cache: {
- provider: memoryCache(),
- },
- routeRules: {
- '/api/*': { swr: 600 },
- '/products/*': { maxAge: 3600, tags: ['products'] },
- '/blog/[...slug]': { maxAge: 300, swr: 60 },
- },
- },
-});
-```
-
-### Pattern syntax
-
-Route patterns support:
-
-- **Static paths**: `/about`, `/api/health`
-- **Dynamic parameters**: `/products/[id]`, `/blog/[slug]`
-- **Rest parameters**: `/docs/[...path]`
-- **Glob wildcards**: `/api/*`
-
-Patterns use the same matching and priority rules as Astro's [file-based routing](/en/guides/routing/#route-priority-order), so more specific patterns take precedence.
-
-### Merging with per-route `cache.set()`
-
-Per-route `cache.set()` calls merge with config-level route rules. Route code can override or extend the defaults set in config.
From 2c71d187c6ea9bfa191f098d3c1f7944ed0eedde Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Tue, 2 Jun 2026 18:17:24 +0200
Subject: [PATCH 05/23] remove the experimental flag page
---
astro.sidebar.ts | 1 -
.../reference/experimental-flags/route-caching.mdx | 12 ------------
2 files changed, 13 deletions(-)
delete mode 100644 src/content/docs/en/reference/experimental-flags/route-caching.mdx
diff --git a/astro.sidebar.ts b/astro.sidebar.ts
index bd07446068dbe..7404633cab9d0 100644
--- a/astro.sidebar.ts
+++ b/astro.sidebar.ts
@@ -156,7 +156,6 @@ export const sidebar = [
group('reference.experimental', {
items: [
'reference/experimental-flags',
- 'reference/experimental-flags/route-caching',
'reference/experimental-flags/client-prerender',
'reference/experimental-flags/content-intellisense',
'reference/experimental-flags/chrome-devtools-workspace',
diff --git a/src/content/docs/en/reference/experimental-flags/route-caching.mdx b/src/content/docs/en/reference/experimental-flags/route-caching.mdx
deleted file mode 100644
index 771552b3fd6f7..0000000000000
--- a/src/content/docs/en/reference/experimental-flags/route-caching.mdx
+++ /dev/null
@@ -1,12 +0,0 @@
----
-title: Experimental route caching
-sidebar:
- label: Route caching
-i18nReady: false
-tableOfContents:
- minHeadingLevel: 2
- maxHeadingLevel: 6
----
-
-import Since from '~/components/Since.astro';
-import ReadMore from '~/components/ReadMore.astro';
From 8c30263d2d7309149f2218efa11b02fa782a347c Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Tue, 2 Jun 2026 19:24:15 +0200
Subject: [PATCH 06/23] links and small rewording in references
---
.../docs/en/reference/api-reference.mdx | 11 ++++----
.../en/reference/cache-provider-reference.mdx | 28 +++++++++++--------
2 files changed, 22 insertions(+), 17 deletions(-)
diff --git a/src/content/docs/en/reference/api-reference.mdx b/src/content/docs/en/reference/api-reference.mdx
index 34c0c9e227e10..278aa5491ab77 100644
--- a/src/content/docs/en/reference/api-reference.mdx
+++ b/src/content/docs/en/reference/api-reference.mdx
@@ -1232,13 +1232,14 @@ content="
### `cache`
-
**Type**: `object | undefined`
+Contains utilities for managing caching behavior for [on-demand rendered](/en/guides/on-demand-rendering/) pages and endpoints.
+
#### `cache.enabled`
@@ -1252,7 +1253,7 @@ Whether caching is active. Returns `false` when no cache provider is configured
-**Type:** `(options: CacheOptions | false) => void`
+**Type:** (options: CacheOptions | false) => void
Sets cache options for the current request. Pass `false` to opt out of caching.
@@ -1264,7 +1265,7 @@ Sets cache options for the current request. Pass `false` to opt out of caching.
**Type:** Readonly\<CacheOptions\>
-Read-only snapshot of the current accumulated cache options, including all merged `maxAge`, `swr`, `etag`, `lastModified`, and `tags` values.
+Provides a read-only snapshot of the current accumulated cache options, including all merged `maxAge`, `swr`, `etag`, `lastModified`, and `tags` values.
#### `cache.tags`
@@ -1273,13 +1274,13 @@ Read-only snapshot of the current accumulated cache options, including all merge
**Type:** `string[]`
-Read-only array of all accumulated cache tags.
+Provides a read-only array of all accumulated cache tags.
#### `cache.invalidate()`
-**Type:** `(options: InvalidateOptions) => Promise`
+**Type:** (options: InvalidateOptions) => Promise\
Purges cached entries. Requires a configured cache provider.
diff --git a/src/content/docs/en/reference/cache-provider-reference.mdx b/src/content/docs/en/reference/cache-provider-reference.mdx
index b31dbdfbe9bd4..47184282f5d73 100644
--- a/src/content/docs/en/reference/cache-provider-reference.mdx
+++ b/src/content/docs/en/reference/cache-provider-reference.mdx
@@ -13,6 +13,8 @@ import { Tabs, TabItem } from '@astrojs/starlight/components';
+Astro Cache Provider API allows you to configure and manage [route caching](/en/guides/routing/#route-caching) behavior. This API includes built-in support for an in-memory cache provider and the ability to create custom providers for various caching strategies and runtimes.
+
## What is a cache provider?
Cache behavior is determined by the configured **cache provider**. Providers fall into two categories:
@@ -231,7 +233,7 @@ import type {
**Type:** `number`
-Time in seconds the response is considered fresh.
+Defines the time in seconds the response is considered fresh.
#### `swr`
@@ -240,7 +242,7 @@ Time in seconds the response is considered fresh.
**Type:** `number`
-Stale-while-revalidate window in seconds. Stale content is served while a fresh response is generated in the background.
+Specifies the stale-while-revalidate window in seconds. Stale content is served while a fresh response is generated in the background.
#### `tags`
@@ -249,7 +251,7 @@ Stale-while-revalidate window in seconds. Stale content is served while a fresh
**Type:** `string[]`
-Cache tags for targeted invalidation. Tags accumulate across multiple `set()` calls.
+A list of cache tags for targeted invalidation. Tags accumulate across multiple `set()` calls.
#### `lastModified`
@@ -258,7 +260,7 @@ Cache tags for targeted invalidation. Tags accumulate across multiple `set()` ca
**Type:** `Date`
-When multiple `set()` calls provide `lastModified`, the most recent date wins.
+Indicates the most recent modification date. When multiple calls to `set()` provide `lastModified`, the most recent call takes precedence.
#### `etag`
@@ -267,7 +269,7 @@ When multiple `set()` calls provide `lastModified`, the most recent date wins.
**Type:** `string`
-Entity tag for conditional requests.
+Specifies the entity tag for conditional requests.
### `CacheProvider`
@@ -286,25 +288,25 @@ A unique name for the provider, used in logs and for identification.
-**Type:** `(options: CacheOptions) => Headers`
+**Type:** (options: CacheOptions) => Headers
-Translates cache options into response headers. Called after the response is rendered but before it is sent to the client. These headers are stripped from the final response.
+Translates cache options into response headers. This is called after the response is rendered but before it is sent to the client. These headers are stripped from the final response.
#### `onRequest()`
-**Type:** `(context: { request: Request; url: URL; waitUntil?: (promise: Promise) => void }, next: MiddlewareNext) => Promise`
+**Type:** (context: \{ request: Request; url: URL; waitUntil?: (promise: Promise\) => void \}, next: MiddlewareNext) => Promise\
-Intercepts requests to implement runtime caching. The `context` includes a `waitUntil` function (when available in the runtime) for background work such as stale-while-revalidate.
+Intercepts requests to implement runtime caching. The `context` includes a `waitUntil()` function (when available in the runtime) for background work such as stale-while-revalidate.
#### `invalidate()`
-**Type:** `(options: InvalidateOptions) => Promise`
+**Type:** (options: InvalidateOptions) => Promise\
Handles purge requests by tag or path.
@@ -316,19 +318,21 @@ Handles purge requests by tag or path.
**Type:** `{ entrypoint: string | URL; config?: Record }`
-The configuration object passed to `experimental.cache.provider`. Use a helper function (e.g. `memoryCache()`) for type-safe configuration.
+The configuration object passed to `cache.provider`. Use a helper function (e.g. `memoryCache()`) for type-safe configuration.
### `CacheProviderFactory`
-**Type:** `(config: Record | undefined) => CacheProvider`
+**Type:** (config: Record\ | undefined) => CacheProvider
The factory function type. Receives the provider's serializable config object from the Astro config.
### `InvalidateOptions`
+Describes the options passed to the provider's `invalidate()` method.
+
#### `path`
From 96d1b8e055e3c31b1dc8699d50f95c54e13187b2 Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Tue, 2 Jun 2026 19:43:10 +0200
Subject: [PATCH 07/23] move route caching to its own page under server
rendering
---
astro.sidebar.ts | 1 +
src/content/docs/en/guides/caching.mdx | 174 ++++++++++++++++++
.../docs/en/guides/content-collections.mdx | 2 +-
src/content/docs/en/guides/routing.mdx | 157 ----------------
.../en/reference/cache-provider-reference.mdx | 2 +-
5 files changed, 177 insertions(+), 159 deletions(-)
create mode 100644 src/content/docs/en/guides/caching.mdx
diff --git a/astro.sidebar.ts b/astro.sidebar.ts
index 7404633cab9d0..809de721c5040 100644
--- a/astro.sidebar.ts
+++ b/astro.sidebar.ts
@@ -80,6 +80,7 @@ export const sidebar = [
'guides/server-islands',
'guides/actions',
'guides/sessions',
+ 'guides/caching',
],
}),
group('guides.upgrade', {
diff --git a/src/content/docs/en/guides/caching.mdx b/src/content/docs/en/guides/caching.mdx
new file mode 100644
index 0000000000000..eb21c8bbf90c3
--- /dev/null
+++ b/src/content/docs/en/guides/caching.mdx
@@ -0,0 +1,174 @@
+---
+title: Route caching
+description: An intro to caching with Astro.
+i18nReady: true
+---
+import Since from '~/components/Since.astro'
+import ReadMore from '~/components/ReadMore.astro'
+
+
+
+Astro provides a platform-agnostic API for caching responses from [on-demand rendered](/en/guides/on-demand-rendering/) pages and endpoints. Cache directives set in your routes are translated into the appropriate headers or runtime behavior depending on your configured cache provider.
+
+Route caching builds on standard [HTTP caching semantics](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching), including `max-age` and [`stale-while-revalidate`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-while-revalidate), with support for tag-based and path-based invalidation, config-level route rules, and pluggable cache providers that adapters can set automatically.
+
+## Configure caching
+
+Route caching requires a cache provider to determine how caching is implemented at runtime. A built-in in-memory provider is available, and custom providers can be implemented for advanced use cases and specific runtimes.
+
+To enable this feature, set a [cache provider](/en/reference/cache-provider-reference/) in your Astro config:
+
+```js title="astro.config.mjs" {6-8} "memoryCache"
+import { defineConfig, memoryCache } from 'astro/config';
+import node from '@astrojs/node';
+
+export default defineConfig({
+ adapter: node({ mode: 'standalone' }),
+ cache: {
+ provider: memoryCache(),
+ },
+});
+```
+
+You can then use [`Astro.cache`](/en/reference/api-reference/#cache) in your `.astro` pages (or `context.cache` for API routes and middleware) to control caching per request. Cache defaults for groups of routes can also be defined declaratively in your config using [`routeRules`](#route-rules).
+
+## Interacting with the cache
+
+The [`cache` object](/en/reference/api-reference/#cache) provides methods for setting cache options, invalidating entries, and checking the current cache state. This object is available in your `.astro` pages as `Astro.cache`, and in API routes and middleware as `context.cache`.
+
+See the [Cache API reference](/en/reference/api-reference/#cache) for more details.
+
+### Checking if caching is enabled
+
+When caching is not enabled, `cache.set()`, `cache.tags`, and `cache.options` will log a warning, and `cache.invalidate()` will throw an error. Before calling these methods, use [`cache.enabled`](/en/reference/api-reference/#cacheenabled):
+
+```astro title="src/pages/products/[id].astro" "Astro.cache.enabled"
+---
+if (Astro.cache.enabled) {
+ const tags = await getProductTags(Astro.params.id);
+ Astro.cache.set({ maxAge: 3600, tags });
+}
+---
+```
+
+This will check whether a cache provider is configured and active. In development mode or when no provider is configured, `cache.enabled` always returns `false`.
+
+### Setting cache options
+
+Call [`cache.set()`](/en/reference/api-reference/#cacheset) with an options object to enable caching for the current response.
+
+The following example caches a page for 2 minutes, serves stale content for 1 minute while revalidating, and tags the response for targeted invalidation:
+
+```astro title="src/pages/index.astro" {4-8}
+---
+export const prerender = false; // Not needed in 'server' mode
+
+Astro.cache.set({
+ maxAge: 120,
+ swr: 60,
+ tags: ['home'],
+});
+---
+
+Cached page
+```
+
+In API routes and middleware, use `context.cache`:
+
+```ts title="src/pages/api/data.ts" {2-5}
+export function GET(context) {
+ context.cache.set({
+ maxAge: 300,
+ tags: ['api', 'data'],
+ });
+ return Response.json({ ok: true });
+}
+```
+
+### Opting out of caching
+
+Call [`cache.set()`](/en/reference/api-reference/#cacheset) with `false` to explicitly opt a request out of caching. This is useful when a matched [route rule](#route-rules) would otherwise cache the response:
+
+```astro title="src/pages/dashboard.astro"
+---
+if (isPersonalized) {
+ Astro.cache.set(false);
+}
+---
+```
+
+### Reading cache state
+
+You can access the current accumulated cache options via [`cache.options`](/en/reference/api-reference/#cacheoptions). This is useful for debugging or when you want to conditionally modify caching based on the current state:
+
+```ts title="src/pages/api/debug.ts"
+const { maxAge, swr, tags } = context.cache.options;
+```
+
+### Invalidating cache entries
+
+You can purge cached entries by tag or path using [`cache.invalidate()`](/en/reference/api-reference/#cacheinvalidate). This is useful for programmatically clearing cached content when it becomes stale, such as after a content update or user action.
+
+The following example creates an API route that invalidates by tag and by path:
+
+```ts title="src/pages/api/revalidate.ts"
+export async function POST(context) {
+ // Invalidate all entries tagged 'data'
+ await context.cache.invalidate({ tags: ['data'] });
+
+ // Invalidate a specific path
+ await context.cache.invalidate({ path: '/api/data' });
+
+ return Response.json({ purged: true });
+}
+```
+
+Tag-based invalidation removes all cached entries whose tags include any of the provided tags. Path-based invalidation is exact-match only (no [glob](/en/guides/imports/#glob-patterns) or wildcard patterns).
+
+## Merge behavior
+
+Multiple calls to [`cache.set()`](/en/reference/api-reference/#cacheset) within a single request are merged according to the following rules:
+
+- **Scalar values** (`maxAge`, `swr`, `etag`): last-write-wins
+- **`lastModified`**: most recent date wins
+- **`tags`**: accumulate across all calls
+
+Middleware, layouts, content loaders, and page code can each contribute cache directives independently.
+
+## Dev mode behavior
+
+In dev mode, the cache API is available so that route code does not need conditional checks, but no actual caching occurs. [`cache.enabled`](/en/reference/api-reference/#cacheenabled) is `false`, and [`cache.set()`](/en/reference/api-reference/#cacheset) and [`cache.invalidate()`](/en/reference/api-reference/#cacheinvalidate) are no-ops. To test your caching locally, build then preview your site.
+
+## Route rules
+
+Route rules allow you to define caching behavior for groups of routes declaratively in your config. This is useful for applying caching to large groups of routes at once.
+
+The following example caches all API routes with stale-while-revalidate, product pages with a 1-hour freshness window, and blog posts for 5 minutes:
+
+```js title="astro.config.mjs" {9-13}
+import { defineConfig, memoryCache } from 'astro/config';
+import node from '@astrojs/node';
+
+export default defineConfig({
+ adapter: node({ mode: 'standalone' }),
+ cache: {
+ provider: memoryCache(),
+ },
+ routeRules: {
+ '/api/*': { swr: 600 },
+ '/products/*': { maxAge: 3600, tags: ['products'] },
+ '/blog/[...slug]': { maxAge: 300, swr: 60 },
+ },
+});
+```
+
+The following route patterns are supported:
+
+- **Static paths**: `/about`, `/api/health`
+- **Dynamic parameters**: `/products/[id]`, `/blog/[slug]`
+- **Rest parameters**: `/docs/[...path]`
+- **Glob wildcards**: `/api/*`
+
+Patterns use the same matching and priority rules as Astro's [file-based routing](#route-priority-order), so more specific patterns take precedence.
+
+Per-route [`cache.set()`](/en/reference/api-reference/#cacheset) calls merge with config-level route rules. Route code can override or extend the defaults set in config. For example, a route rule might set a default `maxAge` for all product pages, but individual pages can call `cache.set()` to customize or disable caching as needed.
diff --git a/src/content/docs/en/guides/content-collections.mdx b/src/content/docs/en/guides/content-collections.mdx
index cb95424e2bae9..cc984d3525c52 100644
--- a/src/content/docs/en/guides/content-collections.mdx
+++ b/src/content/docs/en/guides/content-collections.mdx
@@ -872,7 +872,7 @@ if (error) {
-[Route caching](/en/guides/routing/#route-caching) integrates directly with live content collections. `cache.set()` accepts `CacheHint` and `LiveDataEntry` objects natively, allowing cache hints from loaders to be passed through without manually setting headers.
+[Route caching](/en/guides/caching/) integrates directly with live content collections. `cache.set()` accepts `CacheHint` and `LiveDataEntry` objects natively, allowing cache hints from loaders to be passed through without manually setting headers.
A [live loader](/en/reference/content-loader-reference/#live-loaders) can return a `cacheHint` on individual entries or on the collection as a whole. These hints include `tags` (for targeted invalidation) and `lastModified` (for freshness). When passed to `cache.set()`, they merge with any other cache options already set on the page.
diff --git a/src/content/docs/en/guides/routing.mdx b/src/content/docs/en/guides/routing.mdx
index 72793e1cec615..822bdce9c6508 100644
--- a/src/content/docs/en/guides/routing.mdx
+++ b/src/content/docs/en/guides/routing.mdx
@@ -577,160 +577,3 @@ In this example, only `src/pages/index.astro` and `src/pages/projects/project1.m
## Route caching
-
-
-
-Route caching is a platform-agnostic API for caching responses from [on-demand rendered](/en/guides/on-demand-rendering/) pages and endpoints. Cache directives set in your routes are translated into the appropriate headers or runtime behavior depending on your configured cache provider.
-
-Route caching builds on standard [HTTP caching semantics](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching), including `max-age` and [`stale-while-revalidate`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-while-revalidate), with support for tag-based and path-based invalidation, config-level route rules, and pluggable cache providers that adapters can set automatically.
-
-To enable this feature, set a [cache provider](/en/reference/cache-provider-reference/) in your Astro config:
-
-```js title="astro.config.mjs" {6-8} "memoryCache"
-import { defineConfig, memoryCache } from 'astro/config';
-import node from '@astrojs/node';
-
-export default defineConfig({
- adapter: node({ mode: 'standalone' }),
- cache: {
- provider: memoryCache(),
- },
-});
-```
-
-You can then use [`Astro.cache`](/en/reference/api-reference/#cache) in your `.astro` pages (or `context.cache` for endpoints and middleware) to control caching per request. Cache defaults for groups of routes can also be defined declaratively in your config using [`routeRules`](#route-rules).
-
-### Checking if caching is enabled
-
-Use `cache.enabled` to check whether a cache provider is configured and active. This returns `false` when no provider is configured, or in development mode:
-
-```astro title="src/pages/products/[id].astro" "Astro.cache.enabled"
----
-if (Astro.cache.enabled) {
- const tags = await getProductTags(Astro.params.id);
- Astro.cache.set({ maxAge: 3600, tags });
-}
----
-```
-
-When caching is not enabled, `cache.set()`, `cache.tags`, and `cache.options` will log a warning, and `cache.invalidate()` will throw an error. Use `cache.enabled` to check before calling these methods.
-
-### Setting cache options
-
-Call `cache.set()` with an options object to enable caching for the current response.
-
-The following example caches a page for 2 minutes, serves stale content for 1 minute while revalidating, and tags the response for targeted invalidation:
-
-```astro title="src/pages/index.astro" ins={4-8}
----
-export const prerender = false; // Not needed in 'server' mode
-
-Astro.cache.set({
- maxAge: 120,
- swr: 60,
- tags: ['home'],
-});
----
-
-Cached page
-```
-
-In API routes and middleware, use `context.cache`:
-
-```ts title="src/pages/api/data.ts" ins={2-5}
-export function GET(context) {
- context.cache.set({
- maxAge: 300,
- tags: ['api', 'data'],
- });
- return Response.json({ ok: true });
-}
-```
-
-### Opting out of caching
-
-Call `cache.set(false)` to explicitly opt a request out of caching. This is useful when a matched [route rule](#route-rules) would otherwise cache the response:
-
-```astro title="src/pages/dashboard.astro"
----
-if (isPersonalized) {
- Astro.cache.set(false);
-}
----
-```
-
-### Reading cache state
-
-Access the current accumulated cache options via `cache.options`:
-
-```ts title="src/pages/api/debug.ts"
-const { maxAge, swr, tags } = context.cache.options;
-```
-
-### Invalidating cache entries
-
-Purge cached entries by tag or path using `cache.invalidate()`.
-
-The following example creates an API route that invalidates by tag and by path:
-
-```ts title="src/pages/api/revalidate.ts"
-export async function POST(context) {
- // Invalidate all entries tagged 'data'
- await context.cache.invalidate({ tags: ['data'] });
-
- // Invalidate a specific path
- await context.cache.invalidate({ path: '/api/data' });
-
- return Response.json({ purged: true });
-}
-```
-
-Tag-based invalidation removes all cached entries whose tags include any of the provided tags. Path-based invalidation is exact-match only (no [glob](/en/guides/imports/#glob-patterns) or wildcard patterns).
-
-### Merge behavior
-
-Multiple calls to `cache.set()` within a single request are merged:
-
-- **Scalar values** (`maxAge`, `swr`, `etag`): last-write-wins
-- **`lastModified`**: most recent date wins
-- **`tags`**: accumulate across all calls
-
-Middleware, layouts, content loaders, and page code can each contribute cache directives independently.
-
-### Dev mode behavior
-
-In dev mode, the cache API is available so that route code does not need conditional checks, but no actual caching occurs. `cache.enabled` is `false`, and `cache.set()` and `cache.invalidate()` are no-ops. To test your caching locally, build then preview your site.
-
-### Route rules
-
-Route rules allow you to define caching behavior for groups of routes declaratively in your config. This is useful for applying caching to large groups of routes at once.
-
-The following example caches all API routes with stale-while-revalidate, product pages with a 1-hour freshness window, and blog posts for 5 minutes:
-
-```js title="astro.config.mjs" {9-13}
-import { defineConfig, memoryCache } from 'astro/config';
-import node from '@astrojs/node';
-
-export default defineConfig({
- adapter: node({ mode: 'standalone' }),
- cache: {
- provider: memoryCache(),
- },
- routeRules: {
- '/api/*': { swr: 600 },
- '/products/*': { maxAge: 3600, tags: ['products'] },
- '/blog/[...slug]': { maxAge: 300, swr: 60 },
- },
-});
-```
-
-The following route patterns are supported:
-
-- **Static paths**: `/about`, `/api/health`
-- **Dynamic parameters**: `/products/[id]`, `/blog/[slug]`
-- **Rest parameters**: `/docs/[...path]`
-- **Glob wildcards**: `/api/*`
-
-Patterns use the same matching and priority rules as Astro's [file-based routing](#route-priority-order), so more specific patterns take precedence.
-
-Per-route `cache.set()` calls merge with config-level route rules. Route code can override or extend the defaults set in config. For example, a route rule might set a default `maxAge` for all product pages, but individual pages can call `cache.set()` to customize or disable caching as needed.
diff --git a/src/content/docs/en/reference/cache-provider-reference.mdx b/src/content/docs/en/reference/cache-provider-reference.mdx
index 47184282f5d73..69a20028bfe0a 100644
--- a/src/content/docs/en/reference/cache-provider-reference.mdx
+++ b/src/content/docs/en/reference/cache-provider-reference.mdx
@@ -13,7 +13,7 @@ import { Tabs, TabItem } from '@astrojs/starlight/components';
-Astro Cache Provider API allows you to configure and manage [route caching](/en/guides/routing/#route-caching) behavior. This API includes built-in support for an in-memory cache provider and the ability to create custom providers for various caching strategies and runtimes.
+Astro Cache Provider API allows you to configure and manage [route caching](/en/guides/caching/) behavior. This API includes built-in support for an in-memory cache provider and the ability to create custom providers for various caching strategies and runtimes.
## What is a cache provider?
From 6ada73f079e1527a2bb97307ff155fb98a04076c Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Tue, 2 Jun 2026 22:47:47 +0200
Subject: [PATCH 08/23] consistent formatting for API references
---
.../en/reference/cache-provider-reference.mdx | 23 +++++++++----------
1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/src/content/docs/en/reference/cache-provider-reference.mdx b/src/content/docs/en/reference/cache-provider-reference.mdx
index 69a20028bfe0a..0e43be458392b 100644
--- a/src/content/docs/en/reference/cache-provider-reference.mdx
+++ b/src/content/docs/en/reference/cache-provider-reference.mdx
@@ -226,7 +226,7 @@ import type {
### `CacheOptions`
-#### `maxAge`
+#### `CacheOptions.maxAge`
@@ -235,7 +235,7 @@ import type {
Defines the time in seconds the response is considered fresh.
-#### `swr`
+#### `CacheOptions.swr`
@@ -244,7 +244,7 @@ Defines the time in seconds the response is considered fresh.
Specifies the stale-while-revalidate window in seconds. Stale content is served while a fresh response is generated in the background.
-#### `tags`
+#### `CacheOptions.tags`
@@ -253,7 +253,7 @@ Specifies the stale-while-revalidate window in seconds. Stale content is served
A list of cache tags for targeted invalidation. Tags accumulate across multiple `set()` calls.
-#### `lastModified`
+#### `CacheOptions.lastModified`
@@ -262,7 +262,7 @@ A list of cache tags for targeted invalidation. Tags accumulate across multiple
Indicates the most recent modification date. When multiple calls to `set()` provide `lastModified`, the most recent call takes precedence.
-#### `etag`
+#### `CacheOptions.etag`
@@ -275,7 +275,7 @@ Specifies the entity tag for conditional requests.
Describes a provider used for caching. This requires the `name` and `invalidate()` properties and accepts optional properties.
-#### `name`
+#### `CacheProvider.name`
@@ -284,8 +284,7 @@ Describes a provider used for caching. This requires the `name` and `invalidate(
A unique name for the provider, used in logs and for identification.
-#### `setHeaders()`
-
+#### `CacheProvider.setHeaders()`
**Type:** (options: CacheOptions) => Headers
@@ -293,7 +292,7 @@ A unique name for the provider, used in logs and for identification.
Translates cache options into response headers. This is called after the response is rendered but before it is sent to the client. These headers are stripped from the final response.
-#### `onRequest()`
+#### `CacheProvider.onRequest()`
@@ -302,7 +301,7 @@ Translates cache options into response headers. This is called after the respons
Intercepts requests to implement runtime caching. The `context` includes a `waitUntil()` function (when available in the runtime) for background work such as stale-while-revalidate.
-#### `invalidate()`
+#### `CacheProvider.invalidate()`
@@ -333,7 +332,7 @@ The factory function type. Receives the provider's serializable config object fr
Describes the options passed to the provider's `invalidate()` method.
-#### `path`
+#### `InvalidateOptions.path`
@@ -342,7 +341,7 @@ Describes the options passed to the provider's `invalidate()` method.
Exact path to invalidate. No glob or wildcard support.
-#### `tags`
+#### `InvalidateOptions.tags`
From 1f2a79d35fbf5fb1abe9368aef1c55dea1453125 Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Tue, 2 Jun 2026 22:49:57 +0200
Subject: [PATCH 09/23] replace remaining experimental route caching links
---
src/content/docs/en/reference/content-loader-reference.mdx | 4 ++--
.../docs/en/reference/experimental-flags/advanced-routing.mdx | 2 +-
src/content/docs/en/reference/modules/astro-content.mdx | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/content/docs/en/reference/content-loader-reference.mdx b/src/content/docs/en/reference/content-loader-reference.mdx
index b04f13944c847..5efbef3704a02 100644
--- a/src/content/docs/en/reference/content-loader-reference.mdx
+++ b/src/content/docs/en/reference/content-loader-reference.mdx
@@ -609,7 +609,7 @@ export function myLoader(config): LiveLoader(state: FetchState, next: () => Promise\) => Promise\
-Wraps a render callback with [cache](/en/reference/experimental-flags/route-caching/) provider logic. Handles runtime caching, CDN-based providers, and the no-cache case.
+Wraps a render callback with [cache](/en/guides/caching/) provider logic. Handles runtime caching, CDN-based providers, and the no-cache case.
### `trailingSlash()`
diff --git a/src/content/docs/en/reference/modules/astro-content.mdx b/src/content/docs/en/reference/modules/astro-content.mdx
index 3ef4bb60bf3e4..652fc517edfd1 100644
--- a/src/content/docs/en/reference/modules/astro-content.mdx
+++ b/src/content/docs/en/reference/modules/astro-content.mdx
@@ -543,7 +543,7 @@ const { error } = await getLiveCollection('products');
An object providing guidance on how to cache this collection.
-If you have [experimental route caching](/en/reference/experimental-flags/route-caching/) enabled, pass the cache hint directly to `Astro.cache.set()`:
+If you have [route caching](/en/guides/caching/) enabled, pass the cache hint directly to `Astro.cache.set()`:
```astro title="src/pages/shop/index.astro"
---
@@ -642,7 +642,7 @@ if (error) {
An object providing data that can be used to inform a caching strategy.
-If you have [experimental route caching](/en/reference/experimental-flags/route-caching/) enabled, pass the cache hint directly to `Astro.cache.set()`:
+If you have [route caching](/en/guides/caching/) enabled, pass the cache hint directly to `Astro.cache.set()`:
```astro title="src/pages/shop/[id].astro"
---
From 641c10681ad6b86f1197c888e37b086bca04e2a6 Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Tue, 2 Jun 2026 22:57:11 +0200
Subject: [PATCH 10/23] add memoryCache to `astro/config` module
---
src/content/docs/en/reference/modules/astro-config.mdx | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/content/docs/en/reference/modules/astro-config.mdx b/src/content/docs/en/reference/modules/astro-config.mdx
index 59d987b3f4735..9bfe820d1e241 100644
--- a/src/content/docs/en/reference/modules/astro-config.mdx
+++ b/src/content/docs/en/reference/modules/astro-config.mdx
@@ -138,6 +138,7 @@ import {
envField,
fontProviders,
getViteConfig,
+ memoryCache,
mergeConfig,
passthroughImageService,
sessionDrivers,
@@ -307,6 +308,14 @@ Describes the [built-in provider](/en/reference/font-provider-reference/#built-i
Retrieves the Vite configuration to use by merging a custom Vite configuration object and an optional Astro configuration object. This is useful [to set up Vitest for testing](/en/guides/testing/#vitest).
+### `memoryCache()`
+
+
+**Type:** (config?: MemoryCacheProviderOptions) => CacheProviderConfig\
+
+
+See [`memoryCache()` in the cache provider reference](/en/reference/cache-provider-reference/#built-in-memory-cache-provider).
+
### `mergeConfig()`
See [`mergeConfig()` in the Programmatic API reference](/en/reference/programmatic-reference/#mergeconfig).
From b1138f4c8ab7eda473b90607ef78498747c11a97 Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Tue, 2 Jun 2026 22:59:43 +0200
Subject: [PATCH 11/23] fix broken links
---
src/content/docs/en/guides/caching.mdx | 2 +-
src/content/docs/en/reference/cache-provider-reference.mdx | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/content/docs/en/guides/caching.mdx b/src/content/docs/en/guides/caching.mdx
index eb21c8bbf90c3..5841d40c125f4 100644
--- a/src/content/docs/en/guides/caching.mdx
+++ b/src/content/docs/en/guides/caching.mdx
@@ -169,6 +169,6 @@ The following route patterns are supported:
- **Rest parameters**: `/docs/[...path]`
- **Glob wildcards**: `/api/*`
-Patterns use the same matching and priority rules as Astro's [file-based routing](#route-priority-order), so more specific patterns take precedence.
+Patterns use the same matching and priority rules as Astro's [file-based routing](/en/guides/routing/#route-priority-order), so more specific patterns take precedence.
Per-route [`cache.set()`](/en/reference/api-reference/#cacheset) calls merge with config-level route rules. Route code can override or extend the defaults set in config. For example, a route rule might set a default `maxAge` for all product pages, but individual pages can call `cache.set()` to customize or disable caching as needed.
diff --git a/src/content/docs/en/reference/cache-provider-reference.mdx b/src/content/docs/en/reference/cache-provider-reference.mdx
index 0e43be458392b..9d875ecd72fae 100644
--- a/src/content/docs/en/reference/cache-provider-reference.mdx
+++ b/src/content/docs/en/reference/cache-provider-reference.mdx
@@ -169,7 +169,7 @@ export default defineConfig({
});
```
-The runtime module default-exports a factory that receives the serialized `config` and returns a [`CacheProvider`](#cacheprovider-interface):
+The runtime module default-exports a factory that receives the serialized `config` and returns a [`CacheProvider`](#cacheprovider):
```ts title="my-provider/runtime.ts"
import type { CacheProviderFactory } from 'astro';
From 3c20fc899667823f180d376e94d75b903285abac Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Tue, 2 Jun 2026 23:10:25 +0200
Subject: [PATCH 12/23] fix broken links in translations
---
src/content/docs/fr/reference/content-loader-reference.mdx | 4 ++--
.../docs/fr/reference/experimental-flags/advanced-routing.mdx | 2 +-
src/content/docs/fr/reference/modules/astro-content.mdx | 4 ++--
src/content/docs/ko/reference/content-loader-reference.mdx | 4 ++--
.../docs/ko/reference/experimental-flags/advanced-routing.mdx | 2 +-
src/content/docs/ko/reference/modules/astro-content.mdx | 4 ++--
src/content/docs/zh-cn/reference/content-loader-reference.mdx | 4 ++--
src/content/docs/zh-cn/reference/modules/astro-content.mdx | 4 ++--
8 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/src/content/docs/fr/reference/content-loader-reference.mdx b/src/content/docs/fr/reference/content-loader-reference.mdx
index 43ef62788be05..f2f5111f53052 100644
--- a/src/content/docs/fr/reference/content-loader-reference.mdx
+++ b/src/content/docs/fr/reference/content-loader-reference.mdx
@@ -609,7 +609,7 @@ export function myLoader(config): LiveLoader(state: FetchState, next: () => Promise\) => Promise\
-Enveloppe un rappel de rendu avec la logique du fournisseur de [cache](/fr/reference/experimental-flags/route-caching/). Gère la mise en cache à l'exécution, les fournisseurs basés sur le CDN et le cas sans cache.
+Enveloppe un rappel de rendu avec la logique du fournisseur de [cache](/fr/guides/caching/). Gère la mise en cache à l'exécution, les fournisseurs basés sur le CDN et le cas sans cache.
### `trailingSlash()`
diff --git a/src/content/docs/fr/reference/modules/astro-content.mdx b/src/content/docs/fr/reference/modules/astro-content.mdx
index 127e8fd3f9500..67e4afb6fcb78 100644
--- a/src/content/docs/fr/reference/modules/astro-content.mdx
+++ b/src/content/docs/fr/reference/modules/astro-content.mdx
@@ -543,7 +543,7 @@ const { error } = await getLiveCollection('produits');
Un objet fournissant des instructions sur la manière de mettre en cache cette collection.
-Si vous avez activé la [mise en cache expérimentale des routes](/fr/reference/experimental-flags/route-caching/), transmettez directement l'indication de cache à `Astro.cache.set()` :
+Si vous avez activé la [mise en cache des routes](/fr/guides/caching/), transmettez directement l'indication de cache à `Astro.cache.set()` :
```astro title="src/pages/boutique/index.astro"
---
@@ -642,7 +642,7 @@ if (error) {
Un objet fournissant des données pouvant servir à définir une stratégie de mise en cache.
-Si vous avez activé la [mise en cache expérimentale des routes](/fr/reference/experimental-flags/route-caching/), transmettez directement l'indication de cache à `Astro.cache.set()` :
+Si vous avez activé la [mise en cache des routes](/fr/guides/caching/), transmettez directement l'indication de cache à `Astro.cache.set()` :
```astro title="src/pages/boutique/[id].astro"
---
diff --git a/src/content/docs/ko/reference/content-loader-reference.mdx b/src/content/docs/ko/reference/content-loader-reference.mdx
index 684c37f441a96..0be2fe8867aac 100644
--- a/src/content/docs/ko/reference/content-loader-reference.mdx
+++ b/src/content/docs/ko/reference/content-loader-reference.mdx
@@ -608,7 +608,7 @@ export function myLoader(config): LiveLoader(state: FetchState, next: () => Promise\) => Promise\
-렌더링 콜백을 [캐시](/ko/reference/experimental-flags/route-caching/) 프로바이더 로직으로 래핑합니다. 런타임 캐싱, CDN 기반 프로바이더 및 캐시가 없는 경우를 처리합니다.
+렌더링 콜백을 [캐시](/ko/guides/caching/) 프로바이더 로직으로 래핑합니다. 런타임 캐싱, CDN 기반 프로바이더 및 캐시가 없는 경우를 처리합니다.
### `trailingSlash()`
diff --git a/src/content/docs/ko/reference/modules/astro-content.mdx b/src/content/docs/ko/reference/modules/astro-content.mdx
index b148cd6e52594..486127c43b57a 100644
--- a/src/content/docs/ko/reference/modules/astro-content.mdx
+++ b/src/content/docs/ko/reference/modules/astro-content.mdx
@@ -541,7 +541,7 @@ const { error } = await getLiveCollection('products');
이 컬렉션을 캐시하는 방법에 대한 지침을 제공하는 객체입니다.
-[실험적 라우트 캐싱](/ko/reference/experimental-flags/route-caching/)이 활성화된 경우, 캐시 힌트를 `Astro.cache.set()`에 직접 전달하세요:
+[라우트 캐싱](/ko/guides/caching/)이 활성화된 경우, 캐시 힌트를 `Astro.cache.set()`에 직접 전달하세요:
```astro title="src/pages/shop/index.astro"
---
@@ -640,7 +640,7 @@ if (error) {
캐싱 전략을 결정하는 데 사용될 수 있는 데이터를 제공하는 객체입니다.
-[실험적 라우트 캐싱](/ko/reference/experimental-flags/route-caching/)이 활성화된 경우, 캐시 힌트를 `Astro.cache.set()`에 직접 전달하세요:
+[라우트 캐싱](/ko/guides/caching/)이 활성화된 경우, 캐시 힌트를 `Astro.cache.set()`에 직접 전달하세요:
```astro title="src/pages/shop/[id].astro"
---
diff --git a/src/content/docs/zh-cn/reference/content-loader-reference.mdx b/src/content/docs/zh-cn/reference/content-loader-reference.mdx
index bf1479301f32e..9bb3646258ea2 100644
--- a/src/content/docs/zh-cn/reference/content-loader-reference.mdx
+++ b/src/content/docs/zh-cn/reference/content-loader-reference.mdx
@@ -609,7 +609,7 @@ export function myLoader(config): LiveLoader
Date: Tue, 2 Jun 2026 23:13:01 +0200
Subject: [PATCH 13/23] add more links to existing contents
---
src/content/docs/en/guides/content-collections.mdx | 8 ++++----
.../docs/en/reference/content-loader-reference.mdx | 2 +-
src/content/docs/en/reference/modules/astro-content.mdx | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/content/docs/en/guides/content-collections.mdx b/src/content/docs/en/guides/content-collections.mdx
index cc984d3525c52..21b46aaf19bb2 100644
--- a/src/content/docs/en/guides/content-collections.mdx
+++ b/src/content/docs/en/guides/content-collections.mdx
@@ -872,13 +872,13 @@ if (error) {
-[Route caching](/en/guides/caching/) integrates directly with live content collections. `cache.set()` accepts `CacheHint` and `LiveDataEntry` objects natively, allowing cache hints from loaders to be passed through without manually setting headers.
+[Route caching](/en/guides/caching/) integrates directly with live content collections. [`cache.set()`](/en/reference/api-reference/#cacheset) accepts `CacheHint` and `LiveDataEntry` objects natively, allowing cache hints from loaders to be passed through without manually setting headers.
-A [live loader](/en/reference/content-loader-reference/#live-loaders) can return a `cacheHint` on individual entries or on the collection as a whole. These hints include `tags` (for targeted invalidation) and `lastModified` (for freshness). When passed to `cache.set()`, they merge with any other cache options already set on the page.
+A [live loader](/en/reference/content-loader-reference/#live-loaders) can return a `cacheHint` on individual entries or on the collection as a whole. These hints include `tags` (for targeted invalidation) and `lastModified` (for freshness). When passed to [`cache.set()`](/en/reference/api-reference/#cacheset), they merge with any other cache options already set on the page.
#### Passing cache hints from entries
-Pass the `cacheHint` returned by `getLiveEntry()` or `getLiveCollection()` directly to `cache.set()`.
+Pass the `cacheHint` returned by `getLiveEntry()` or `getLiveCollection()` directly to [`cache.set()`](/en/reference/api-reference/#cacheset).
The following example passes the loader's cache hint and adds a `maxAge` to control how long the response stays fresh:
@@ -922,7 +922,7 @@ Astro.cache.set({ maxAge: 300, swr: 60 });
#### Invalidating by entry
-`cache.invalidate()` also accepts a `LiveDataEntry`, invalidating all cached responses tagged with that entry's cache tags.
+[`cache.invalidate()`](/en/reference/api-reference/#cacheinvalidate) accepts a `LiveDataEntry`, invalidating all cached responses tagged with that entry's cache tags.
The following example invalidates the cached response for a specific product entry:
diff --git a/src/content/docs/en/reference/content-loader-reference.mdx b/src/content/docs/en/reference/content-loader-reference.mdx
index 5efbef3704a02..7a49956612012 100644
--- a/src/content/docs/en/reference/content-loader-reference.mdx
+++ b/src/content/docs/en/reference/content-loader-reference.mdx
@@ -609,7 +609,7 @@ export function myLoader(config): LiveLoader
Date: Tue, 2 Jun 2026 23:39:44 +0200
Subject: [PATCH 14/23] remove stale heading in `guides/routing`
---
src/content/docs/en/guides/routing.mdx | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/content/docs/en/guides/routing.mdx b/src/content/docs/en/guides/routing.mdx
index 822bdce9c6508..30e5a801b2913 100644
--- a/src/content/docs/en/guides/routing.mdx
+++ b/src/content/docs/en/guides/routing.mdx
@@ -575,5 +575,3 @@ In this example, only `src/pages/index.astro` and `src/pages/projects/project1.m
- _utils.js
- **project1.md**
-
-## Route caching
From 29a451e8cc911813392b06948bc5a34d085c60dd Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Wed, 3 Jun 2026 17:29:40 +0200
Subject: [PATCH 15/23] add a redirection
---
public/_redirects | 1 +
1 file changed, 1 insertion(+)
diff --git a/public/_redirects b/public/_redirects
index c9ed6c8034af6..9c6e4cc11cc19 100644
--- a/public/_redirects
+++ b/public/_redirects
@@ -53,6 +53,7 @@
/:lang/reference/experimental-flags/live-content-collections/ /:lang/guides/content-collections/#live-content-collections
/:lang/reference/experimental-flags/preserve-scripts-order/ /:lang/guides/client-side-scripts/
/:lang/reference/experimental-flags/static-import-meta-env/ /:lang/guides/environment-variables/
+/:lang/reference/experimental-flags/route-caching/ /:lang/guides/caching/
# Very old docs site redirects
# Once upon a time these URLs existed, so we try to keep them meaning something.
From 21fec9c3d456e2f0f100b63fee6b2a6c9163857b Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Wed, 3 Jun 2026 23:40:11 +0200
Subject: [PATCH 16/23] reorganize and reword a bit content collections
guidance
---
.../docs/en/guides/content-collections.mdx | 59 ++++++++++---------
1 file changed, 30 insertions(+), 29 deletions(-)
diff --git a/src/content/docs/en/guides/content-collections.mdx b/src/content/docs/en/guides/content-collections.mdx
index 21b46aaf19bb2..cddb7c60c71df 100644
--- a/src/content/docs/en/guides/content-collections.mdx
+++ b/src/content/docs/en/guides/content-collections.mdx
@@ -872,17 +872,21 @@ if (error) {
-[Route caching](/en/guides/caching/) integrates directly with live content collections. [`cache.set()`](/en/reference/api-reference/#cacheset) accepts `CacheHint` and `LiveDataEntry` objects natively, allowing cache hints from loaders to be passed through without manually setting headers.
+When live loaders provide [cache hints](/en/reference/content-loader-reference/#live-loaders), `getLiveEntry()` and `getLiveCollection()` return a `cacheHint` object. This allows you to control the [caching behavior](/en/guides/caching/) of your routes without manually setting headers.
-A [live loader](/en/reference/content-loader-reference/#live-loaders) can return a `cacheHint` on individual entries or on the collection as a whole. These hints include `tags` (for targeted invalidation) and `lastModified` (for freshness). When passed to [`cache.set()`](/en/reference/api-reference/#cacheset), they merge with any other cache options already set on the page.
+Cache hints include [`tags`](/en/reference/content-loader-reference/#cachehinttags) for targeted invalidation and [`lastModified`](/en/reference/content-loader-reference/#cachehintlastmodified) to keep cached data fresh. You can also combine the cache hints with your own [cache options](/en/reference/cache-provider-reference/#cacheoptions) to further customize caching behavior.
-#### Passing cache hints from entries
+
+See the [Content Loader Reference](/en/reference/content-loader-reference/) for more about implementing cache hints in your live loaders.
+
-Pass the `cacheHint` returned by `getLiveEntry()` or `getLiveCollection()` directly to [`cache.set()`](/en/reference/api-reference/#cacheset).
+#### Entry-level cache hints
+
+Pass the `cacheHint` returned by `getLiveEntry()` to [`Astro.cache.set()`](/en/reference/api-reference/#cacheset) to apply the loader's recommended caching strategy.
The following example passes the loader's cache hint and adds a `maxAge` to control how long the response stays fresh:
-```astro title="src/pages/products/[id].astro"
+```astro title="src/pages/products/[id].astro" {4,10-12}
---
import { getLiveEntry } from 'astro:content';
@@ -895,15 +899,16 @@ if (error) {
if (cacheHint) {
Astro.cache.set(cacheHint);
}
+
Astro.cache.set({ maxAge: 300 });
---
{entry.data.name}
```
-A [`LiveDataEntry`](/en/reference/content-loader-reference/#livedataentry) can also be passed directly. Astro extracts its `cacheHint` automatically:
+You can also pass a [`LiveDataEntry`](/en/reference/content-loader-reference/#livedataentry) directly to let Astro extract its `cacheHint` automatically:
-```astro title="src/pages/products/[id].astro"
+```astro title="src/pages/products/[id].astro" {4,10}
---
import { getLiveEntry } from 'astro:content';
@@ -920,31 +925,13 @@ Astro.cache.set({ maxAge: 300, swr: 60 });
{entry.data.name}
```
-#### Invalidating by entry
-
-[`cache.invalidate()`](/en/reference/api-reference/#cacheinvalidate) accepts a `LiveDataEntry`, invalidating all cached responses tagged with that entry's cache tags.
-
-The following example invalidates the cached response for a specific product entry:
-
-```ts title="src/pages/api/revalidate.ts"
-import { getLiveEntry } from 'astro:content';
-
-export async function POST(context) {
- const { entry } = await getLiveEntry('products', 'featured');
- if (entry) {
- await context.cache.invalidate(entry);
- }
- return Response.json({ ok: true });
-}
-```
-
#### Collection-level cache hints
When fetching a full collection with `getLiveCollection()`, Astro merges cache hints from the collection response and all individual entries: tags are accumulated, and the most recent `lastModified` wins.
The following example passes the merged cache hint from a collection and sets a 10-minute freshness window:
-```astro title="src/pages/products/index.astro"
+```astro title="src/pages/products/index.astro" {4,10-12}
---
import { getLiveCollection } from 'astro:content';
@@ -965,9 +952,23 @@ Astro.cache.set({ maxAge: 600 });
```
-
-See the [Content Loader Reference](/en/reference/content-loader-reference/) for more about implementing cache hints in your live loaders.
-
+#### Invalidating by entry
+
+You can invalidate cached entries by passing a `LiveDataEntry` to [`cache.invalidate()`](/en/reference/api-reference/#cacheinvalidate). This allows you to target specific cached responses for invalidation based on the entry's cache tags, without needing to clear the entire cache.
+
+The following example invalidates the cached response for a specific product entry:
+
+```ts title="src/pages/api/revalidate.ts"
+import { getLiveEntry } from 'astro:content';
+
+export async function POST(context) {
+ const { entry } = await getLiveEntry('products', 'featured');
+ if (entry) {
+ await context.cache.invalidate(entry);
+ }
+ return Response.json({ ok: true });
+}
+```
## Using JSON Schema files in your editor
From 905b4aa163f068fca257e5b6b0f477c8e308512b Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Thu, 4 Jun 2026 13:52:56 +0200
Subject: [PATCH 17/23] add links and reword slightly
`content-loader-reference`
---
.../docs/en/reference/content-loader-reference.mdx | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/content/docs/en/reference/content-loader-reference.mdx b/src/content/docs/en/reference/content-loader-reference.mdx
index 7a49956612012..8fe0c92b6aa80 100644
--- a/src/content/docs/en/reference/content-loader-reference.mdx
+++ b/src/content/docs/en/reference/content-loader-reference.mdx
@@ -609,7 +609,7 @@ export function myLoader(config): LiveLoader{entry.data.description}
```
-Without route caching enabled, you can use cache hints to set response headers manually for your own caching strategy:
+Without a cache provider, you can use cache hints to set response headers manually for your own caching strategy:
```astro title="src/pages/store/[id].astro"
---
@@ -1460,6 +1460,8 @@ If the loader does not return a `rendered` property for an entry, the `See the content collection guide to learn how to [use cache hints at entry-level](/en/guides/content-collections/#entry-level-cache-hints).
+
### `LiveDataCollection`
@@ -1490,9 +1492,11 @@ An array of [`LiveDataEntry`](#livedataentry) objects.
An optional object providing guidance on how to cache this collection. This object will be merged with the cache hints defined for each individual entry, if provided.
+See the content collection guide to learn how to [use cache hints at collection-level](/en/guides/content-collections/#collection-level-cache-hints).
+
### `CacheHint`
-An object that loaders can return through the `cacheHint` property in [`LiveDataCollection`](#livedatacollection) or [`LiveDataEntry`](#livedataentry) to provide hints to assist in caching the response. This contains the following properties:
+An object that loaders can return through the `cacheHint` property in [`LiveDataCollection`](#livedatacollection) or [`LiveDataEntry`](#livedataentry) to provide hints to assist in [caching the response](/en/guides/caching/). This contains the following properties:
#### `CacheHint.tags`
From b141ab3f9ccde89cc01d28ec06b1b1cb8da19c67 Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Thu, 4 Jun 2026 13:57:24 +0200
Subject: [PATCH 18/23] add a link to the caching guide in `api-reference`
---
src/content/docs/en/reference/api-reference.mdx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/content/docs/en/reference/api-reference.mdx b/src/content/docs/en/reference/api-reference.mdx
index 278aa5491ab77..cd78827c63753 100644
--- a/src/content/docs/en/reference/api-reference.mdx
+++ b/src/content/docs/en/reference/api-reference.mdx
@@ -1240,6 +1240,8 @@ content="
Contains utilities for managing caching behavior for [on-demand rendered](/en/guides/on-demand-rendering/) pages and endpoints.
+See the [caching guide](/en/guides/caching/) for more information on how to use caching in your Astro project.
+
#### `cache.enabled`
From e2256c1ac7f0db67d7a08eb7eb525114876088c7 Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Thu, 4 Jun 2026 13:59:51 +0200
Subject: [PATCH 19/23] tweak the wording and add links in
`modules/astro-content`
---
src/content/docs/en/reference/modules/astro-content.mdx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/content/docs/en/reference/modules/astro-content.mdx b/src/content/docs/en/reference/modules/astro-content.mdx
index fbec6db1aecd0..4b6d5fe077dcb 100644
--- a/src/content/docs/en/reference/modules/astro-content.mdx
+++ b/src/content/docs/en/reference/modules/astro-content.mdx
@@ -543,7 +543,7 @@ const { error } = await getLiveCollection('products');
An object providing guidance on how to cache this collection.
-If you have [route caching](/en/guides/caching/) enabled, pass the cache hint directly to [`Astro.cache.set()`](/en/reference/api-reference/#cacheset):
+If you have [configured a cache provider](/en/guides/caching/#configure-caching), pass the cache hint directly to [`Astro.cache.set()`](/en/reference/api-reference/#cacheset):
```astro title="src/pages/shop/index.astro"
---
@@ -642,7 +642,7 @@ if (error) {
An object providing data that can be used to inform a caching strategy.
-If you have [route caching](/en/guides/caching/) enabled, pass the cache hint directly to `Astro.cache.set()`:
+If you have [configured a cache provider](/en/guides/caching/#configure-caching), pass the cache hint directly to [`Astro.cache.set()`](/en/reference/api-reference/#cacheset):
```astro title="src/pages/shop/[id].astro"
---
From 949d4de2ee5545c413d08e7e86c80c11ea20c056 Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Thu, 4 Jun 2026 15:37:42 +0200
Subject: [PATCH 20/23] more links and slight rewording in
`cache-provider-reference`
---
.../en/reference/cache-provider-reference.mdx | 34 ++++++++++++++-----
1 file changed, 25 insertions(+), 9 deletions(-)
diff --git a/src/content/docs/en/reference/cache-provider-reference.mdx b/src/content/docs/en/reference/cache-provider-reference.mdx
index 9d875ecd72fae..b64e97920c657 100644
--- a/src/content/docs/en/reference/cache-provider-reference.mdx
+++ b/src/content/docs/en/reference/cache-provider-reference.mdx
@@ -6,7 +6,6 @@ i18nReady: true
---
import Since from '~/components/Since.astro';
import ReadMore from '~/components/ReadMore.astro';
-import { Tabs, TabItem } from '@astrojs/starlight/components';
@@ -57,6 +56,8 @@ export default defineConfig({
**Default:** `{ max: 1000 }`
+Configures the in-memory cache provider.
+
#### `max`
@@ -65,10 +66,15 @@ export default defineConfig({
**Default:** `1000`
-Maximum number of entries to keep in cache. When the cache exceeds this limit, the least recently used entry is evicted.
+Defines the maximum number of entries to keep in cache. When the cache exceeds this limit, the least recently used entry is evicted.
#### `query`
+
+
+**Type:** `{ sort?: boolean; include?: string[]; exclude?: string[]; }`
+
+
Controls how query parameters are handled in cache keys.
##### `query.sort`
@@ -79,7 +85,9 @@ Controls how query parameters are handled in cache keys.
**Default:** `true`
-Sort query parameters alphabetically so that parameter order does not affect the cache key. Set to `false` to disable sorting, and cache URLs with different query parameter order separately. This is useful when parameter order is significant.
+Determines whether query parameters should be sorted alphabetically. This is useful when parameter order is significant and to ensure that their order does not affect the cache key.
+
+Set to `false` to disable sorting, and cache URLs with different query parameter orders separately.
##### `query.exclude`
@@ -89,9 +97,9 @@ Sort query parameters alphabetically so that parameter order does not affect the
**Default:** `['utm_*', 'fbclid', 'gclid', 'gbraid', 'wbraid', 'dclid', 'msclkid', 'twclid', 'li_fat_id', 'mc_cid', 'mc_eid', '_ga', '_gl', '_hsenc', '_hsmi', '_ke', 'oly_anon_id', 'oly_enc_id', 'rb_clickid', 's_cid', 'vero_id', 'wickedid', 'yclid', '__s', 'ref']`
-Exclude query parameters whose names match these patterns from the cache key. Supports glob wildcards (e.g. `"utm_*"`). Cannot be used together with `include`.
+Lists the query parameters to exclude from the cache key. This supports glob wildcards (e.g. `"utm_*"`) and, by default, excludes common tracking and analytics parameters.
-By default, common tracking and analytics parameters are excluded. Set to `[]` to include all query parameters in the cache key:
+Set to `[]` to include all query parameters in the cache key:
```js title="astro.config.mjs"
memoryCache({
@@ -99,6 +107,8 @@ memoryCache({
});
```
+An error is thrown if used together with [`include`](#queryinclude).
+
##### `query.include`
@@ -106,7 +116,7 @@ memoryCache({
**Type:** `string[]`
-Only include these query parameter names in the cache key. All other parameters are ignored, including the default tracking parameter exclusions. Cannot be used together with `exclude`.
+Lists the query parameter names to include in the cache key. When set, all other parameters are ignored, including default tracking parameter exclusions.
The following example only uses `page` and `sort` parameters in the cache key, ignoring all others:
@@ -116,6 +126,8 @@ memoryCache({
});
```
+An error is thrown if used together with [`exclude`](#queryexclude).
+
### Cache key behavior
The memory provider automatically normalizes cache keys for better hit rates:
@@ -134,7 +146,7 @@ A cache provider has two parts:
1. **The runtime module** — A file that **default-exports** a `CacheProviderFactory` function. This module is bundled into your SSR output, so it must be runtime-agnostic: avoid Node.js built-in modules (e.g. `node:fs`, `node:path`) unless your target runtime supports them.
-2. **The config helper** — A function exported for users to call in `astro.config.mjs`. It returns a [`CacheProviderConfig` object](#cacheproviderconfig) that tells Astro where to find the runtime module and what options to pass it. This is the same pattern used by `memoryCache()` from `astro/config`.
+2. **The config helper** — A function exported for users to call in `astro.config.mjs`. It returns a [`CacheProviderConfig` object](#cacheproviderconfig) that tells Astro where to find the runtime module and what options to pass it. This is the same pattern used by the built-in [`memoryCache()` provider](#built-in-memory-cache-provider).
The following example shows a config helper that accepts typed options and points to a runtime module:
@@ -226,6 +238,10 @@ import type {
### `CacheOptions`
+Describes the options passed to a cache provider.
+
+Learn how to [use cache options](/en/guides/caching/#setting-cache-options) to control caching behavior.
+
#### `CacheOptions.maxAge`
@@ -251,7 +267,7 @@ Specifies the stale-while-revalidate window in seconds. Stale content is served
**Type:** `string[]`
-A list of cache tags for targeted invalidation. Tags accumulate across multiple `set()` calls.
+A list of cache tags for targeted invalidation. Tags accumulate across multiple [`cache.set()`](/en/reference/api-reference/#cacheset) calls.
#### `CacheOptions.lastModified`
@@ -260,7 +276,7 @@ A list of cache tags for targeted invalidation. Tags accumulate across multiple
**Type:** `Date`
-Indicates the most recent modification date. When multiple calls to `set()` provide `lastModified`, the most recent call takes precedence.
+Indicates the most recent modification date. When multiple calls to [`cache.set()`](/en/reference/api-reference/#cacheset) provide `lastModified`, the most recent call takes precedence.
#### `CacheOptions.etag`
From 0bbea5abe6a555b247aaa54bc523d2cb952837af Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Thu, 4 Jun 2026 16:41:14 +0200
Subject: [PATCH 21/23] small tweaks in the caching guide
---
src/content/docs/en/guides/caching.mdx | 8 +++-----
src/content/docs/en/guides/upgrade-to/v7.mdx | 2 +-
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/src/content/docs/en/guides/caching.mdx b/src/content/docs/en/guides/caching.mdx
index 5841d40c125f4..93bdb169a0c75 100644
--- a/src/content/docs/en/guides/caching.mdx
+++ b/src/content/docs/en/guides/caching.mdx
@@ -10,11 +10,11 @@ import ReadMore from '~/components/ReadMore.astro'
Astro provides a platform-agnostic API for caching responses from [on-demand rendered](/en/guides/on-demand-rendering/) pages and endpoints. Cache directives set in your routes are translated into the appropriate headers or runtime behavior depending on your configured cache provider.
-Route caching builds on standard [HTTP caching semantics](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching), including `max-age` and [`stale-while-revalidate`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-while-revalidate), with support for tag-based and path-based invalidation, config-level route rules, and pluggable cache providers that adapters can set automatically.
+Route caching builds on standard [HTTP caching semantics](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching), including [`max-age`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control#max-age) and [`stale-while-revalidate`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-while-revalidate), with support for tag-based and path-based invalidation, config-level route rules, and pluggable cache providers that adapters can set automatically.
## Configure caching
-Route caching requires a cache provider to determine how caching is implemented at runtime. A built-in in-memory provider is available, and custom providers can be implemented for advanced use cases and specific runtimes.
+Route caching requires a cache provider to determine how caching is implemented at runtime. A [built-in in-memory provider](/en/reference/cache-provider-reference/#built-in-memory-cache-provider) is available, and custom providers can be implemented for advanced use cases and specific runtimes.
To enable this feature, set a [cache provider](/en/reference/cache-provider-reference/) in your Astro config:
@@ -40,7 +40,7 @@ The [`cache` object](/en/reference/api-reference/#cache) provides methods for se
### Checking if caching is enabled
-When caching is not enabled, `cache.set()`, `cache.tags`, and `cache.options` will log a warning, and `cache.invalidate()` will throw an error. Before calling these methods, use [`cache.enabled`](/en/reference/api-reference/#cacheenabled):
+When caching is not configured, `cache.set()`, `cache.tags`, and `cache.options` log a warning, and `cache.invalidate()` throws an error. To avoid this, wrap your caching logic in a conditional check using [`cache.enabled`](/en/reference/api-reference/#cacheenabled). Its value is always `false` when no provider is configured or in development mode.
```astro title="src/pages/products/[id].astro" "Astro.cache.enabled"
---
@@ -51,8 +51,6 @@ if (Astro.cache.enabled) {
---
```
-This will check whether a cache provider is configured and active. In development mode or when no provider is configured, `cache.enabled` always returns `false`.
-
### Setting cache options
Call [`cache.set()`](/en/reference/api-reference/#cacheset) with an options object to enable caching for the current response.
diff --git a/src/content/docs/en/guides/upgrade-to/v7.mdx b/src/content/docs/en/guides/upgrade-to/v7.mdx
index 7d8e58e777c4b..9904d08eacbe2 100644
--- a/src/content/docs/en/guides/upgrade-to/v7.mdx
+++ b/src/content/docs/en/guides/upgrade-to/v7.mdx
@@ -92,7 +92,7 @@ export default defineConfig({
rustCompiler: true,
routeCaching: true,
},
-})
+});
```
#### Experimental features now stable:
From d6e3cd0d01c45e41ebf978806b55b42c71540975 Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Thu, 4 Jun 2026 19:30:32 +0200
Subject: [PATCH 22/23] fix highlighting in the v7 upgrade guide
---
src/content/docs/en/guides/upgrade-to/v7.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/content/docs/en/guides/upgrade-to/v7.mdx b/src/content/docs/en/guides/upgrade-to/v7.mdx
index 9904d08eacbe2..141a9e02c932c 100644
--- a/src/content/docs/en/guides/upgrade-to/v7.mdx
+++ b/src/content/docs/en/guides/upgrade-to/v7.mdx
@@ -84,7 +84,7 @@ Experimental flags allow you to opt in to features while they are in early devel
Remove these experimental flags from your Astro config if you were previously using them:
-```js del={5-7} title="astro.config.mjs"
+```js del={5-6} title="astro.config.mjs"
import { defineConfig } from 'astro/config';
export default defineConfig({
From 4ac0cf627f9666b8da68072816cd1e6d6e4eda28 Mon Sep 17 00:00:00 2001
From: Armand Philippot
Date: Mon, 8 Jun 2026 22:00:19 +0200
Subject: [PATCH 23/23] unnecessary comma
Co-authored-by: Yan <61414485+yanthomasdev@users.noreply.github.com>
---
src/content/docs/en/reference/cache-provider-reference.mdx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/content/docs/en/reference/cache-provider-reference.mdx b/src/content/docs/en/reference/cache-provider-reference.mdx
index b64e97920c657..cd26578e701be 100644
--- a/src/content/docs/en/reference/cache-provider-reference.mdx
+++ b/src/content/docs/en/reference/cache-provider-reference.mdx
@@ -87,7 +87,7 @@ Controls how query parameters are handled in cache keys.
Determines whether query parameters should be sorted alphabetically. This is useful when parameter order is significant and to ensure that their order does not affect the cache key.
-Set to `false` to disable sorting, and cache URLs with different query parameter orders separately.
+Set to `false` to disable sorting and cache URLs with different query parameter orders separately.
##### `query.exclude`