Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Control caching

boatramp already sets a sensible Cache-Control on every file it serves, adds a strong ETag, answers conditional requests with 304, and honors Range — you do not configure any of that. This page covers the one thing you do control: overriding Cache-Control per path, so hashed assets cache for a year and HTML always revalidates.

When to override

Reach for a header rule when the automatic default is wrong for a path. Two cases cover almost everything:

  • Long-lived immutable assets — files whose name changes when their content does (app.4f3a2b2c.js). Cache them for a year.
  • Always-revalidate documents — HTML, JSON feeds, anything that keeps its URL across deploys. Force a check on every request.

boatramp’s defaults already do this for content-hashed filenames and HTML. Add rules when your paths do not match that shape (an unhashed /vendor/ bundle, a hand-written /api/config.json), or when you want a blanket policy.

Set Cache-Control per path

Header rules live in project.cfg under routing.headers. Each rule has a path matches pattern and a set map; every matching rule applies, in order.

(
    routing: (
        headers: [
            // Fingerprinted assets — safe to cache for a year.
            (matches: "/assets/**", set: {
                "Cache-Control": "public, max-age=31536000, immutable",
            }),
            // Documents — always revalidate so a new deploy is picked up.
            (matches: "**.html", set: {
                "Cache-Control": "public, max-age=0, must-revalidate",
            }),
        ],
        // Blanket fallback for anything no rule matches.
        cache: (default: "public, max-age=3600"),
    ),
)

A matching routing.headers rule wins; cache.default fills the gaps; boatramp’s per-file defaults apply where neither is set. Rules are folded into the immutable deployment at sync, so they roll back with the content. Run boatramp validate to check the patterns before you publish.

Verify the response

Request an asset and read the headers back:

curl -sI https://my-site.example/assets/app.4f3a2b2c.js
HTTP/2 200
cache-control: public, max-age=31536000, immutable
etag: "9f86d081884c7d65..."
accept-ranges: bytes
vary: accept-encoding

The etag and accept-ranges are automatic. To confirm revalidation, send the tag back — an unchanged asset answers 304:

curl -sI https://my-site.example/assets/app.4f3a2b2c.js \
  -H 'If-None-Match: "9f86d081884c7d65..."'
HTTP/2 304
etag: "9f86d081884c7d65..."

Reference