Conversation
✅ Deploy Preview for astro-docs-2 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Lunaria Status Overview🌕 This pull request will trigger status changes. Learn moreBy default, every PR changing files present in the Lunaria configuration's You can change this by adding one of the keywords present in the Tracked Files
Warnings reference
|
sarah11918
left a comment
There was a problem hiding this comment.
Wow, @ascorbic ! Only a very few small comments from me (most of them just adding specific link anchors that were probably too annoying for you to hunt down in the moment).
I think this one just needs to go straight to @yanthomasdev , for whom I've left all the commas! 🎉
|
|
||
| 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/) 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. |
There was a problem hiding this comment.
| A [live loader](/en/reference/content-loader-reference/) 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()`, they merge with any other cache options already set on the page. |
| } | ||
| ``` | ||
|
|
||
| Tag-based invalidation removes all cached entries whose tags include any of the provided tags. Path-based invalidation is exact-match only (no glob or wildcard patterns). |
There was a problem hiding this comment.
| Tag-based invalidation removes all cached entries whose tags include any of the provided tags. Path-based invalidation is exact-match only (no glob or wildcard patterns). | |
| 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). |
Totally optional. Just remembered that we have a section about this, so could link there if we thought it was useful.
| - **Rest parameters**: `/docs/[...path]` | ||
| - **Glob wildcards**: `/api/*` | ||
|
|
||
| Patterns use the same matching and priority rules as Astro's [file-based routing](/en/guides/routing/), so more specific patterns take precedence. |
There was a problem hiding this comment.
| Patterns use the same matching and priority rules as Astro's [file-based routing](/en/guides/routing/), 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. |
|
|
||
| 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. |
There was a problem hiding this comment.
I'm wondering whether somewhere around here in the intro, it's worth comparing this feature to ISR? (Astro's solution to X, sometimes known as ISR; Astro's answer to what's normally solved with ISR; While other frameworks attempt to do X with ISR, Astro's route caching accomplishes X+...)
Totally not necessary of course, just thinking how we could have an SEO hit for Astro + ISR and also be able to point people somewhere when they say "what about ISR?"
|
|
||
| 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. |
There was a problem hiding this comment.
| 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` 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. |
|
|
||
| ### 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. |
There was a problem hiding this comment.
| 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. | |
| 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. |
|
|
||
| ### `CacheNotEnabled` | ||
|
|
||
| Thrown when `Astro.cache` or `context.cache` is used but `experimental.cache` is not configured. The error message explains how to enable the feature. |
There was a problem hiding this comment.
| Thrown when `Astro.cache` or `context.cache` is used but `experimental.cache` is not configured. The error message explains how to enable the feature. | |
| Thrown when `Astro.cache` or `context.cache` is used, but `experimental.cache` is not configured. The error message explains how to enable the feature. |
|
|
||
| ## Dev mode behavior | ||
|
|
||
| In dev mode, the cache API is available so route code does not need conditional checks, but no actual caching occurs. `cache.set()` calls are accepted silently, and `cache.invalidate()` is a no-op. |
There was a problem hiding this comment.
| In dev mode, the cache API is available so route code does not need conditional checks, but no actual caching occurs. `cache.set()` calls are accepted silently, and `cache.invalidate()` is a no-op. | |
| In dev mode, the cache API is available so that route code does not need conditional checks, but no actual caching occurs. `cache.set()` calls are accepted silently, and `cache.invalidate()` is a no-op. |
ArmandPhilippot
left a comment
There was a problem hiding this comment.
The feature looks great! I left a few suggestions, some are nitpickings and others are for consistency with the rest of the docs (e.g. use of tables which don't look very good on small devices).
|
|
||
| To enable this feature, configure `experimental.cache` with a cache provider in your Astro config: | ||
|
|
||
| ```js title="astro.config.mjs" ins={2} ins="memoryCache" |
There was a problem hiding this comment.
I was confused when scanning the page before reading because the node import is highlighted but not its use so I first thought this was a leftover.
Would it makes sense to use ins (green) for what's new and regular highlighting for node (both the import and its use)?
| ```js title="astro.config.mjs" ins={2} ins="memoryCache" | |
| ```js title="astro.config.mjs" {2,5} ins="memoryCache" |
|
|
||
| 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={3-7} |
There was a problem hiding this comment.
Slight misalignment:
| ```astro title="src/pages/index.astro" ins={3-7} | |
| ```astro title="src/pages/index.astro" ins={4-8} |
| <h1>{entry.data.name}</h1> | ||
| ``` | ||
|
|
||
| A `LiveDataEntry` can also be passed directly. Astro extracts its `cacheHint` automatically: |
There was a problem hiding this comment.
nit: for those who don't know that this is the return type for getLiveEntry() maybe a link to the type can help:
| A `LiveDataEntry` can also be passed directly. Astro extracts its `cacheHint` automatically: | |
| A [`LiveDataEntry`](/en/reference/content-loader-reference/#livedataentry) can also be passed directly. Astro extracts its `cacheHint` automatically: |
| **Default:** `{ max: 1000 }` | ||
|
|
||
| </p> | ||
|
|
There was a problem hiding this comment.
Looking at the preview, I feel we miss en sentence here to separate the two headings. Maybe something like:
| To further control how entries are cached, you can use the following options. | |
|
|
||
| 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 (`{ entrypoint, config }`) 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`. |
There was a problem hiding this comment.
Maybe a link to the reference is more helpful than the parentheses?
| 2. **The config helper** — A function exported for users to call in `astro.config.mjs`. It returns a `CacheProviderConfig` object (`{ entrypoint, config }`) 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 `memoryCache()` from `astro/config`. |
| }); | ||
| ``` | ||
|
|
||
| The runtime module default-exports a factory that receives the serialized `config` and returns a `CacheProvider`: |
There was a problem hiding this comment.
I think a link can be helpful for those who want to learn more about the API:
| The runtime module default-exports a factory that receives the serialized `config` and returns a `CacheProvider`: | |
| The runtime module default-exports a factory that receives the serialized `config` and returns a [`CacheProvider`](#cacheprovider-interface): |
| ``` | ||
|
|
||
| ### `CacheProvider` interface | ||
|
|
There was a problem hiding this comment.
We usually have an introductory sentence here. Maybe something like:
| Describes a provider used for caching. This requires the `name` and `invalidate()` properties and accepts optional properties. | |
|
|
||
| </p> | ||
|
|
||
| Optional. 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. |
There was a problem hiding this comment.
I'll note we usually don't start the description with "Optional"/"Required"... but maybe this is something to consider for the API block (alongside "Type", "Default"...).
|
|
||
| <p> | ||
|
|
||
| **Type:** `Readonly<CacheOptions>` |
There was a problem hiding this comment.
I know this is described right above but for someone redirected to this section, a link to the full object might be helpful:
| **Type:** `Readonly<CacheOptions>` | |
| **Type:** <code>Readonly\<<a href="#cacheoptions>CacheOptions</a>\></code> |
| | Property | Type | Description | | ||
| | -------- | -------------------- | --------------------------------------------------------------------- | | ||
| | `path` | `string` | Exact path to invalidate. No glob or wildcard support. | | ||
| | `tags` | `string \| string[]` | Tag or tags to invalidate. All entries with matching tags are purged. | |
There was a problem hiding this comment.
Same as above, we usually don't use tables and this is not the most usable on small devices.
| | `swr` | `number` | Stale-while-revalidate window in seconds. Stale content is served while a fresh response is generated in the background. | | ||
| | `tags` | `string[]` | Cache tags for targeted invalidation. Tags accumulate across multiple `set()` calls. | | ||
| | `lastModified` | `Date` | When multiple `set()` calls provide `lastModified`, the most recent date wins. | | ||
| | `etag` | `string` | Entity tag for conditional requests. | |
There was a problem hiding this comment.
Oh, it seems I forgot to add this comment... 🤦🏽 (with the screenshot my comment about tables/small devices will make more sense I guess)
I'm a bit confused by this. We usually don't use tables in docs because they look a bit awful on small devices. We usually use headings for each. This how it looks using Firefox iPhone 11 preview:

Description (required)
Adds docs for the experimental route caching flag. See the code PR: withastro/astro#15579 and the RFC: withastro/roadmap#1245 for more details
Also updates the live collections docs to refer to route caching in the sections about cache hints.
Related issues & labels (optional)