Koa Cache Control Middleware
raw JSON → 2.0.0 verified Thu Apr 23 auth: no javascript maintenance
The `koa-cache-control` package provides Koa middleware for declarative management of HTTP `Cache-Control` headers. Currently stable at version 2.0.0, it offers a simple API to configure caching behaviors, including `no-cache`, `max-age`, `public`, `private`, and `no-store`. The package helps consolidate common caching patterns, such as automatically setting `max-age=0` when `no-cache` is enabled. While its release cadence has been relatively slow, with its last major update aligning with Koa 2.x, it specifically targets Koa applications, providing a more integrated approach than manually manipulating headers directly. It supports both Koa 1.x (generator-based) and Koa 2.x (async/await based) applications.
Common errors
error TypeError: app.use is not a function ↓
cause Attempting to use Koa middleware with a non-Koa application instance or an incorrectly initialized Koa app.
fix
Ensure you have
import Koa from 'koa'; const app = new Koa(); and that app is correctly instantiated before using .use(). error Cache-Control header not appearing or having unexpected values ↓
cause Middleware is not applied or is being overridden by other middleware/manual header settings, or options are conflicting (e.g., `noCache` overriding `maxAge`).
fix
Verify
app.use(cacheControl(...)) is called early in your middleware chain. Check for other middleware or manual ctx.set('Cache-Control', ...) calls that might conflict. Inspect the generated header using browser developer tools or curl -v. Warnings
breaking While v2.0.0 explicitly supports Koa 2.x (async/await), many older examples and documentation excerpts may still show Koa 1.x generator function syntax (e.g., `function *(next){ yield next; }`). Ensure your application's middleware functions are updated to `async (ctx, next) => { await next(); }` for Koa 2.x compatibility. ↓
fix Rewrite generator functions to async/await syntax: `app.use(async (ctx, next) => { /* ... */ await next(); });`
gotcha Setting the `noCache` option will automatically apply `max-age=0` and remove `sMaxAge`, `staleIfError`, and `staleWhileRevalidate` from the generated `Cache-Control` header. This implicit behavior might override other caching directives you intended. ↓
fix Be aware of option interactions. If `no-cache` is desired but with a specific `max-age` or other directives, manually construct the header or ensure `noCache` is not set.
gotcha The package uses `ctx.cacheControl` (or `this.cacheControl` in Koa 1.x) to allow overriding default options within specific routes. Ensure you set this property *before* `ctx.body` is set or the response is sent, as headers are typically finalized early in the response lifecycle. ↓
fix Always set `ctx.cacheControl` at the beginning of your route handler or before calling `await next()` if you need to modify caching behavior based on subsequent logic.
Install
npm install koa-cache-control yarn add koa-cache-control pnpm add koa-cache-control Imports
- cacheControl wrong
import { cacheControl } from 'koa-cache-control';correctimport cacheControl from 'koa-cache-control'; - cacheControl (CJS)
const cacheControl = require('koa-cache-control'); - Context property
ctx.cacheControl = { maxAge: 60 };
Quickstart
import Koa from 'koa';
import cacheControl from 'koa-cache-control';
const app = new Koa();
// Apply middleware with default maxAge of 5 seconds
app.use(cacheControl({
maxAge: 5
}));
// Example route where cache control is set dynamically
app.use(async (ctx, next) => {
if (ctx.path === '/no-cache-page') {
ctx.cacheControl = {
noCache: true
};
ctx.body = 'This page will not be cached.';
} else if (ctx.path === '/long-cache-page') {
ctx.cacheControl = {
maxAge: 3600, // 1 hour
public: true
};
ctx.body = 'This page is cached for 1 hour.';
} else {
ctx.body = 'Default cached page (5 seconds).';
}
await next();
});
app.listen(3000, () => {
console.log('Koa server running on http://localhost:3000');
console.log('Try http://localhost:3000/ and http://localhost:3000/no-cache-page');
});