{ frankenphp } :8000 { root * /app/public encode gzip zstd # Vite emits content-hashed filenames, so a build asset URL never changes # meaning. Same for uploaded media: PublicImageUploadRules stores every # upload under a fresh UUID (and ResponsiveImage derives its variants from # that name), so replacing an image produces a new URL rather than new bytes # at the old one. Both are safe to pin for a year. @immutable path /build/* /storage/* header @immutable Cache-Control "public, max-age=31536000, immutable" # Brand assets ship inside the image under stable filenames, so a rebrand # reuses the same URL. One day plus Caddy's ETag revalidation keeps repeat # views cheap without pinning an outdated logo in browsers. @brand path /brand/* header @brand Cache-Control "public, max-age=86400" php_server }