Location Block Deep Dive
The location block defines different behavior for different URL paths in Nginx. Mastering matching priority, try_files, and the difference between alias and root is at the core of advanced Nginx configuration.
Location Matching Modifiers — Complete Guide
location [modifier] path { ... }
| Modifier | Name | Description |
|---|---|---|
= | Exact match | Matches only when URL is exactly equal; immediately used when matched |
^~ | Priority prefix | Prefix match + skips regex checks |
~ | Case-sensitive regex | Regex pattern matching |
~* | Case-insensitive regex | Regex matching regardless of case |
| (none) | Plain prefix | Longest prefix match wins |
Matching Priority Step by Step
When the same URL matches multiple location blocks, Nginx processes them in this order:
Step 1: = (Exact match) check
location = /images/logo.png { /* matched immediately if exact */ }
Step 2: ^~ (Priority prefix) check — longest match selected
location ^~ /images/ { /* skips regex checks if matched */ }
Step 3: ~ / ~* (Regex) check — first match in file order
location ~* \.(png|jpg|gif)$ { /* first regex match in file */ }
Step 4: Plain prefix — longest match selected
location /images/ { /* if no regex matched */ }
Step 5: / — final fallback for everything
location / { try_files $uri $uri/ =404; }
Priority Summary
1st: = (exact match)
2nd: ^~ (priority prefix, longest wins)
3rd: ~, ~* (regex, first match in file order)
4th: plain prefix (longest match wins)
Practical Priority Example
server {
listen 80;
root /var/www/html;
location = /favicon.ico { log_not_found off; access_log off; }
location ^~ /static/ { expires 30d; add_header Cache-Control "public"; }
location ~* \.(png|jpg|jpeg|gif|webp|svg|ico)$ { expires 7d; }
location ~* \.(js|css)$ { expires 1y; add_header Cache-Control "public, immutable"; }
location /api/ { proxy_pass http://127.0.0.1:8080; }
location / { try_files $uri $uri/ =404; }
}
| Request URL | Matched Block | Reason |
|---|---|---|
/favicon.ico | = /favicon.ico | Exact match |
/static/app.js | ^~ /static/ | Priority prefix (skips regex) |
/images/logo.png | `~* .(png | ...)$` |
/api/users | /api/ prefix | No regex match, prefix match |
/about | / fallback | Nothing else matched |
try_files — Complete Guide
try_files tries files or URIs in order and uses the last entry as a fallback if none are found.
Syntax
try_files file1 file2 ... fallback;
Static File Serving
location / {
# Try in order:
# 1. Does the file $uri exist? (/about.html)
# 2. Does the directory $uri/ exist? (/about/)
# 3. Return 404 if nothing found
try_files $uri $uri/ =404;
}
SPA (React/Vue) Client-Side Routing
location / {
# If file doesn't exist, fall back to index.html (React Router handles it)
try_files $uri $uri/ /index.html;
}
Redirect to Named Location
location / {
try_files $uri $uri/ @fallback;
}
location @fallback {
proxy_pass http://127.0.0.1:8080;
}
With PHP FastCGI
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
alias vs root — Path Handling Difference
Both root and alias specify file system paths, but they behave differently.
root: Prepends path to Location URI
location /images/ {
root /var/www;
}
# GET /images/logo.png
# → Actual file: /var/www/images/logo.png
# (root + URI = /var/www + /images/logo.png)
alias: Replaces Location URI with specified path
location /images/ {
alias /var/www/static/photos/;
}
# GET /images/logo.png
# → Actual file: /var/www/static/photos/logo.png
# (/images/ replaced by /var/www/static/photos/)
alias tip: Always end the
aliasvalue with/. For regex locations,aliasis often more appropriate thanroot.
Named Locations (@named location)
Named locations starting with @ cannot be accessed externally — they are only referenced internally by try_files, error_page, etc.
server {
location / {
try_files $uri $uri/ @backend;
}
error_page 404 @not_found;
error_page 500 502 503 504 @error;
location @backend {
proxy_pass http://127.0.0.1:8080;
}
location @not_found {
return 302 /404.html;
}
location @error {
return 302 /500.html;
}
}
Summary
| Concept | Key Point |
|---|---|
Exact match (=) | Exact URL match, highest priority |
Priority prefix (^~) | Prefix match + skips regex checks |
Regex (~, ~*) | First match in file order |
| Plain prefix | Longest match wins |
try_files | Try files in order, use fallback if not found |
root | Prepends root path to URI |
alias | Fully replaces URI with specified path |
@named | Internal reference only location |