1. The problem I’m having:
We have an SPA we are serving with Caddy. We want to set cache control headers on any request that results in serving the index.html
file. Our config currently uses try_files {path} /index.html
so that any static file request is resolved, and everything else serves index.html
. I’d like to be able to control cache headers separately for this.
Currently I have /
and /index.html
changing the cache control, and that’s working. But I guess I don’t understand how to catch anything that isn’t a static file. I’m very new to caddy and have mostly copy/pasted other’s configs. I’ve looked over the docs, but I don’t understand how I can select based on the result of the caddy resolution. For example, I can imagine that what I want is to change the header on any response that sends the index.html
file, rather than the request path.
2. Caddyfile
# global options
{
admin off # theres no need for the admin api in railway's environment
persist_config off # storage isn't persistent anyway
auto_https off # railway handles https for us, this would cause issues if left enabled
# runtime logs
log {
format json # set runtime log format to json mode
}
# server options
servers {
trusted_proxies static private_ranges # trust railway's proxy
}
}
# site block, listens on the $PORT environment variable, automatically assigned by railway
:{$PORT} {
# access logs
log {
format json # set access log format to json mode
}
@index {
path /
path /index.html
}
header @index {
Cache-Control "no-cache, no-store, must-revalidate"
}
# health check for railway
respond /health 200
# serve from the 'dist' folder (Vite builds into the 'dist' folder)
root * apps/web/dist
# enable gzipping responses
encode gzip
# serve files from 'dist'
file_server
# if path doesn't exist, redirect it to 'index.html' for client side routing
try_files {path} /index.html
}