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.

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.
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.
npm install koa-cache-control
yarn add koa-cache-control
pnpm add koa-cache-control

Sets up a basic Koa application using `koa-cache-control` with default settings and demonstrates dynamic override on specific routes.

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