To set up Caddy for serving a Single Page Application (SPA) like a React app with react-router, you need to handle routing such that all navigation requests are routed to index.html
, while also serving the static assets correctly.
Directory Structure on Remote Storage
The build folder is stored at http://my-minio-server:9000/website/short-videos (S3 bucket) which contains the index.html
and js
/css
files. see below for examples
- http://my-minio-server:9000/website/short-videos/index.html
- http://my-minio-server:9000/website/short-videos/assets/xxx.js
Caddy Configuration
The goal is to serve the React app at shorts.xiaohai-huang.net, with the build output of the app stored on remote storage as mentioned above.
Below is a Caddy configuration to serve your SPA correctly:
shorts.xiaohai-huang.net {
rewrite * /website/short-videos{uri}
reverse_proxy my-minio-server:9000 {
@error status 404
handle_response @error {
rewrite * /website/short-videos/index.html
reverse_proxy my-minio-server:9000
}
}
}
Explanation
- Site Address: The
shorts.xiaohai-huang.net
is your site's domain. - Rewrite Rule: The
rewrite * /website/short-videos{uri}
ensures that all requests are rewritten to include the path to your build folder on the MinIO server. - Reverse Proxy: The
reverse_proxy my-minio-server:9000
forwards requests to your MinIO server. - Error Handling: The
@error status 404
block handles 404 errors. If a requested URL is not found (common with SPAs), it rewrites the request to index.html, ensuring that the React app's routing can take over.
It is often necessary to override the Host header with the configured upstream address when proxying to HTTPS, such that the Host header matches the TLS ServerName value.
reverse_proxy https://example.com {
header_up Host {upstream_hostport}
}
See https://caddyserver.com/docs/caddyfile/directives/reverse_proxy#https
In this example, the app is served at the index route (shorts.xiaohai-huang.net) aka. /
. So the base
public path of the react app should be set to /
in your react build config.