# 0049. Built assets are immutable; AJAX responses are never cached

- **Status:** Accepted
- **Date:** 2026-09-24

## Context

`.htaccess` compressed fonts (which grows a woff2), had no Brotli and no `webp` expiry. The server's default
expiry also reached PHP responses without their own `Cache-Control` — and the storage search fetches its own
page URL for JSON.

## Decision

`web/.htaccess` takes Molino's block: Brotli where the module exists, gzip otherwise, no font compression, a year
of expiry for images including WebP, `immutable` on `/build` and `/assets`. `Controller::beforeAction()` sends
`Vary: X-Requested-With` on every response and `no-store` on AJAX ones (as Molino's).

## Consequences

- Built files must keep content-hashed names — the production build does.
- The server-specific lines Molino carries (`AddHandler`, `FollowSymLinks`) are not here.
