Appearance
Bubbling Cacheability
A page is often built from several cached parts: Data from the data cache, cached components and API routes that are fetched during SSR. Each part has its own max age and cache tags.
By bubbling the cacheability of these parts, their max age, stale if error duration and cache tags are merged into the route cache and/or the CDN headers of the current request. This way, a cached page never outlives the data it shows, and purging a cache tag also purges the pages that use it.
Values
Bubbling is set with a bubbleCacheability option, which accepts:
true- Bubble to the route cache and the CDN headers'route'- Only bubble to the route cache'cdn'- Only bubble to the CDN headersfalse- Don't bubble
Bubbling only has an effect if the route cache or the CDN feature is enabled.
What Bubbles
| Value | Route cache | CDN headers |
|---|---|---|
| Max age | Lowest value wins | max-age, lowest value wins, caps s-maxage |
| Stale if error | Lowest value wins, except 0 | stale-if-error, lowest value wins, except 0 |
| Cache tags | Added | Added to the cache tag header |
| Uncacheable | The route becomes uncacheable | max-age=0, no-store, s-maxage lowered to 0, Cache-Control: private |
- A max age of
'permanent'never lowers the max age. - A stale if error duration of
0(for example a part that doesn't define one) doesn't lower the value either. - If a part is returned from cache, the remaining time until it expires bubbles, not its original max age.
- Shared caches use
s-maxageinstead ofmax-age. If the page or a merged API response sets ans-maxage, the header gets the lowest lifetime for shared caches of all sources: Theirs-maxageor, without one, theirmax-age. A page withs-maxage=86400and a part with a max age of 60 seconds getss-maxage=60, and a page withmax-age=0doesn't get thes-maxage=3600of an API route. - Bubbling never makes a route cacheable. The route must still be marked as cacheable using useRouteCache.
Where to Use It
Component Cache
Set the bubble-cacheability prop on <RenderCacheable>. By default, nothing bubbles.
vue
<template>
<RenderCacheable max-age="1h" :cache-tags="['navbar']" bubble-cacheability>
<Navbar />
</RenderCacheable>
</template>This bubbles the values of the props and the values set with useComponentCache, when the component is rendered or returned from cache.
Data Cache
Pass the option to useDataCache or useDataCacheCallback. By default, nothing bubbles.
typescript
const { value, addToCache } = await useDataCache('weather', null, {
bubbleCacheability: true,
})useDataCache bubbles the cached item when a value is returned from cache, and the values passed to addToCache when it is called. They bubble even if the data cache doesn't store the item: if it is disabled at runtime, not enabled for the request, the key contains a ? or reading the item failed. The page still shows the data, so it must not outlive it.
typescript
const weather = await useDataCacheCallback(
'weather',
async (helper) => {
const response = await $fetch('/api/getWeather')
if (helper && import.meta.server) {
helper.setMaxAge('5m').addTags(['weather'])
}
return response
},
null,
{ bubbleCacheability: 'route' },
)useDataCacheCallback also bubbles a call to setUncacheable() on the helper, and the stale item when a stale value is returned.
In a Nuxt app context, pass null as the event. In a Nitro server context, the event is required.
API Routes
The interceptor returned by useCacheAwareFetchInterceptor bubbles the CDN headers and the route cache values of API routes that are fetched during SSR. Here, bubbling is enabled by default:
typescript
const { data } = await useFetch(
'/api/load-users',
useCacheAwareFetchInterceptor(),
)- Route cache: The values of the API route's route cache helper bubble, including
setUncacheable(). A page that fetches an uncacheable API route becomes uncacheable as well. This only applies to relative URLs. It also applies to API routes requested with another method thanGETorHEAD, such asPOST, whose responses are never stored themselves. - CDN headers: The CDN header of the API route is merged, including
privateandno-store. Its route cache values don't affect the CDN headers.
An API route that doesn't use the route cache, or is excluded from it with route.applies or enabledForRequest, has no route cache values to bubble. If such an API route returns data specific to the request, mark the page as uncacheable yourself.