Nuxt · npm

Cache Nuxt by tag, in one line.

@canner-ca/nuxt-cache sets the Cache-Control and Surrogate-Key headers Canner needs — correctly, every time — in any Nuxt place you can set response headers: pages, server routes, and middleware. Zero dependencies.

$npm install @canner-ca/nuxt-cache

Use it

Pages

Pass the request event. On the client useRequestEvent() is undefined, so the call is a safe no-op.

<script setup>
import { cache } from '@canner-ca/nuxt-cache';

const route = useRoute();
const { data: post } = await useAsyncData(() => fetchPost(route.params.slug));

cache(useRequestEvent(), { ttl: 3600, tags: [post.value.id, 'blog-listing'] });
</script>

Server routes

In server/api or server/routes, pass the event directly.

// server/api/posts.get.ts
import { cache } from '@canner-ca/nuxt-cache';

export default defineEventHandler((event) => {
  cache(event, { ttl: 3600, tags: ['blog-listing'] });
  return getPosts();
});

Server middleware

Mark matching paths cacheable for whatever renders them.

// server/middleware/cache.ts
import { cache } from '@canner-ca/nuxt-cache';

export default defineEventHandler((event) => {
  if (event.path.startsWith('/blog/')) {
    cache(event, { ttl: 3600, tags: ['blog-listing'] });
  }
});

Why it's safe with Nuxt

Nuxt mostly just works: client navigation fetches payloads from separate URLs, so a page URL only ever returns its HTML document. The one same-URL exception is the SPA shell Nuxt returns when a request sends x-nuxt-no-ssr — Canner's proxy passes those requests straight through, so only the real server-rendered document is ever cached. You don't configure any of that.

Options

ttlRequired. Seconds Canner may serve the cached response — sets s-maxage.tagsString, number, or array. Sets Surrogate-Key. Numbers are coerced; duplicates and whitespace tags are dropped.browserTtlOptional. Seconds the visitor's browser may cache (sets max-age). Omit to keep tag purges instant.

It only ever adds headers

The helper never strips or mutates anything your app set. It does not remove Set-Cookie — Canner already declines to cache a response that sets a cookie, so you get a development-only warning, and your cookie is left untouched. A bad TTL sets no headers and warns; a null target is a no-op (the client render pass); only an unsupported target throws.

Then point your CMS at Canner

The code side is done. The other half is two copy-paste values — the webhook URL and an Authorization header — shown pre-filled in the dashboard under Settings → Caching. Full caching guide.

Source and issues: tools/nuxt-cache/ in the canner repo on GitHub. Licensed MIT. Also available for @canner-ca/astro-cache and @canner-ca/next-cache.