Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
bee219c
Update v7 upgrade guide: experimental flags, src/app.ts, @astrojs/db …
matthewp May 27, 2026
5ec2ba0
remove Astro DB and Advanced Routing from upgrade guide
ArmandPhilippot Jun 2, 2026
000454b
reorganize the references part
ArmandPhilippot Jun 2, 2026
7e8756b
reorganize the guide parts
ArmandPhilippot Jun 2, 2026
2c71d18
remove the experimental flag page
ArmandPhilippot Jun 2, 2026
8c30263
links and small rewording in references
ArmandPhilippot Jun 2, 2026
96d1b8e
move route caching to its own page under server rendering
ArmandPhilippot Jun 2, 2026
6ada73f
consistent formatting for API references
ArmandPhilippot Jun 2, 2026
1f2a79d
replace remaining experimental route caching links
ArmandPhilippot Jun 2, 2026
641c106
add memoryCache to `astro/config` module
ArmandPhilippot Jun 2, 2026
b1138f4
fix broken links
ArmandPhilippot Jun 2, 2026
3c20fc8
fix broken links in translations
ArmandPhilippot Jun 2, 2026
9206e25
add more links to existing contents
ArmandPhilippot Jun 2, 2026
7dfee4e
Merge branch 'v7' into armand/stable-route-caching
ArmandPhilippot Jun 2, 2026
2c09e01
remove stale heading in `guides/routing`
ArmandPhilippot Jun 2, 2026
29a451e
add a redirection
ArmandPhilippot Jun 3, 2026
21fec9c
reorganize and reword a bit content collections guidance
ArmandPhilippot Jun 3, 2026
905b4aa
add links and reword slightly `content-loader-reference`
ArmandPhilippot Jun 4, 2026
b141ab3
add a link to the caching guide in `api-reference`
ArmandPhilippot Jun 4, 2026
e2256c1
tweak the wording and add links in `modules/astro-content`
ArmandPhilippot Jun 4, 2026
949d4de
more links and slight rewording in `cache-provider-reference`
ArmandPhilippot Jun 4, 2026
0bbea5a
small tweaks in the caching guide
ArmandPhilippot Jun 4, 2026
d6e3cd0
fix highlighting in the v7 upgrade guide
ArmandPhilippot Jun 4, 2026
790d763
Merge branch 'v7' into armand/stable-route-caching
ArmandPhilippot Jun 8, 2026
4ac0cf6
unnecessary comma
ArmandPhilippot Jun 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion astro.sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export const sidebar = [
'guides/server-islands',
'guides/actions',
'guides/sessions',
'guides/caching',
],
}),
group('guides.upgrade', {
Expand Down Expand Up @@ -148,14 +149,14 @@ 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',
],
}),
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',
Expand Down
1 change: 1 addition & 0 deletions public/_redirects
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
172 changes: 172 additions & 0 deletions src/content/docs/en/guides/caching.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
---
title: Route caching
description: An intro to caching with Astro.
i18nReady: true
---
import Since from '~/components/Since.astro'
import ReadMore from '~/components/ReadMore.astro'

<p><Since v="7.0.0" /></p>

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`](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](/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:

```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`.

<ReadMore>See the [Cache API reference](/en/reference/api-reference/#cache) for more details.</ReadMore>

### Checking if caching is enabled

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"
---
if (Astro.cache.enabled) {
const tags = await getProductTags(Astro.params.id);
Astro.cache.set({ maxAge: 3600, tags });
}
---
```

### 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'],
});
---

<html><body>Cached page</body></html>
```

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](/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.
102 changes: 102 additions & 0 deletions src/content/docs/en/guides/content-collections.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,108 @@ if (error) {
---
```

### Caching live data

<p><Since v="7.0.0" /></p>

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.

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.

<ReadMore>
See the [Content Loader Reference](/en/reference/content-loader-reference/) for more about implementing cache hints in your live loaders.
</ReadMore>

#### 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" {4,10-12}
---
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 });
---

<h1>{entry.data.name}</h1>
```

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" {4,10}
---
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 });
---

<h1>{entry.data.name}</h1>
```

#### 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" {4,10-12}
---
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 });
---

<ul>
{entries.map((p) => <li>{p.data.name}</li>)}
</ul>
```

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

<p><Since v="4.13.0" /></p>
Expand Down
19 changes: 10 additions & 9 deletions src/content/docs/en/guides/upgrade-to/v7.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -78,27 +78,28 @@ 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.

If you had previously opted in to the Rust compiler via the experimental flag, you can now remove it from your configuration:
Remove these experimental flags from your Astro config if you were previously using them:

```js title="astro.config.mjs" del={4-6}
```js del={5-6} title="astro.config.mjs"
import { defineConfig } from 'astro/config';

export default defineConfig({
experimental: {
rustCompiler: true,
routeCaching: true,
},
});
```

If you encounter any issues with the Rust compiler, please report them on [GitHub](https://github.com/withastro/astro/issues).
#### 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).

- `routeCaching`: Route caching is now enabled by default for improved performance.

## Removed

Expand Down
Loading
Loading