When building a single-page application (SPA), you often need Nginx to serve static assets directly while routing all other requests to your index.html
file without modifying the URL. This is crucial for client-side routing to work properly.
Here's how to configure Nginx to handle this scenario:
server {
listen 80;
server_name example.com;
# Serve static files directly
location /static/ {
alias /path/to/your/static/files/;
try_files $uri =404;
}
# All other requests serve index.html without redirect
location / {
root /path/to/your/spa;
try_files $uri /index.html;
}
}
The configuration uses several important Nginx directives:
alias
: Maps requests to the exact file system path for static assetstry_files
: Attempts to serve the requested file, falling back to index.htmlroot
: Sets the base directory for the SPA files
After making changes, always test your Nginx configuration:
sudo nginx -t
sudo systemctl reload nginx
For SPAs using HTML5 history mode (like Vue Router or React Router), this setup ensures:
# All these will serve index.html while preserving the URL:
example.com/about
example.com/user/123/profile
example.com/any/nested/path
For production environments, consider adding caching headers:
location /static/ {
alias /path/to/your/static/files/;
expires 1y;
add_header Cache-Control "public";
try_files $uri =404;
}
When building single-page applications (SPAs), we often need Nginx to serve static assets from specific directories while routing all other requests to a single HTML file (typically index.html) without altering the URL. This is crucial because:
- SPAs use client-side routing (React Router, Vue Router, etc.)
- Direct URL access should work without server redirection
- Static assets need separate optimization (caching, compression)
server {
listen 80;
server_name yourdomain.com;
# Static assets handling
location /static/ {
alias /path/to/your/static/files/;
expires 1y;
add_header Cache-Control "public";
try_files $uri =404;
}
# All other requests go to index.html while preserving URL
location / {
root /path/to/your/app;
try_files $uri /index.html;
}
}
The magic happens with try_files:
try_files $uri /index.html;
This attempts to serve the requested file first, then falls back to index.html while maintaining the original URL in the browser.
Handling API Proxying
location /api/ {
proxy_pass http://backend-api;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
Gzip Compression for Static Files
location /static/ {
gzip on;
gzip_types text/plain text/css application/json application/javascript;
# ... rest of static config
}
- Trailing slashes matter: "/static" vs "/static/" behave differently
- Root vs alias: Use alias when the URI doesn't match the filesystem path
- Caching headers: Set different Cache-Control for assets vs HTML
Always validate your config before applying:
nginx -t
And reload after changes:
nginx -s reload