Serve a single-page app with nginx: every route to index.html, hashed assets cached
Runs in your browser. Nothing you type is sent anywhere. Checked against sources on 22 Oct 2026.A single-page app gives 404 on refresh because nginx looks for a file at /dashboard that does not exist. The fix is try_files $uri $uri/ /index.html, which sends every unknown path to the app. This config adds it, keeps index.html uncached so a new deploy shows at once, caches hashed assets for a year, and refuses hidden files such as .env and .git.
Set the options you need, or start from the example.
The result is made again every time you change something.
Copy it or download it. Nothing was sent anywhere.
Most nginx configurations are copied from an answer written for another version and another job. This generator writes the whole file for yours, with a comment on every block, and leaves out the mistakes that are easy to copy.
| Preset | What it writes |
|---|---|
| Reverse proxy | proxy_pass to your app with Host, X-Real-IP and X-Forwarded headers, an upload limit, optional WebSocket upgrades |
| Static site | root and index, try_files with a real 404, assets cached for 30 days |
| Single-page app | every route to index.html, index.html never cached, hashed assets cached for a year |
| Redirect domain | every address of the old domain to the new one in one hop, path kept or dropped |
The nginx traps it avoids. An add_header inside a location silently drops every header of the server block, so the security headers are written once and caching uses expires instead. text/html is always compressed, so listing it in gzip_types only adds a warning. HTTP/2 is switched on with http2 on in nginx 1.25.1 and later; turn off the version switch for the older listen form.
The rest of the article, and all 6 questions about Nginx Config Generator, are on the Nginx Config Generator page.
Choose Reverse proxy, type your domain and the address the app listens on, such as http://127.0.0.1:3000. The config forwards every request with the Host and X-Forwarded headers, so the app sees the real domain, visitor address and https. Turn on WebSocket if the app uses them.
Nginx looks for a file matching the address, such as /settings, and finds none. The Single-page app preset adds try_files $uri $uri/ /index.html, which serves index.html for every path that is not a real file, so the app's router can show the right page.
In nginx, an add_header inside a location block replaces every add_header from the server block, it does not add to them. That is why this config writes the headers once at server level and uses the expires directive for caching, which sets Cache-Control without add_header.
Yes, nginx will not start with a missing certificate file. Load only the HTTP server block first, run certbot certonly --webroot -w /var/www/letsencrypt with your domain, then add the HTTPS blocks. The default paths are the ones certbot writes under /etc/letsencrypt/live.
Rates and rules change; check the source before you rely on a figure.
Still stuck? Ask about Nginx Config Generator and anybody who knows can answer. No account needed.
Same job, other tools: Sitemap Index Generator – Split a large site into numbered sitemaps with an index file.
On the related tools: Cron Expression Generator – Generate a cron expression by choosing when the job should run · Google Analytics URL Builder – The five utm parameters GA4 reads, with the naming traps flagged.