Configuring Client-Side Routing for React SPA with Caddy
/ 2 min read
DISCLAIMER
The blog post was written by me. However, to solve this issue, I consulted a LLM, which was quite helpful in writing this.
I was building a static site with React and React Router. Unfortunately, there were two issues:
- It crashed, when the site was reloaded
- It was not possible to access sub-pages directly, e.g.
blog.metters.dev
worked, butblog.metters.dev/posts
did not.
This is because the request is handled on server-side instead of client-side.
The server-side routing does not know about the subpage and returns 404.
To solve this, Caddy must be configured to serve the main index.html
file for all incoming requests, except for static assets. Kind of like a catch-all route.
There are two directives that need to be added and configured, in order to fix this issue: file_server
and try_files
.
Caddy directive file_server
When the root of the website or a directory is requested, Caddy will attempt to serve an index file. The defaults are index.html
or index.txt
.
This directive should be set anyway, if Caddy is serving a static site.
Caddy directive try_files
{path}
On reload try to serve the file at the exact path.{path}/
If that fails, append a trailing slash to the requested path. If a default HTML file is available the request succeeds./index.html
Otherwise, returnindex.html
as fallback.
With these two directives, Caddy ensures that page reloads are routed correctly.
Resources
- Caddy documentation on directives
- Caddy documentation on the directive try_files
- Caddy documentation on the directive file_server