Nginx Cheatsheet
Rewrites and Redirects
Use this Nginx reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
return — Preferred for Redirects
# Permanent redirect (301) return 301 https://$host$request_uri; # Temporary redirect (302) return 302 /new-location; # Redirect with exact new URL return 301 https://newdomain.com$request_uri; # Return a status with no body return 204; # Return status + plain text body return 200 "OK";
Prefer
returnoverrewritefor redirects — it's faster (no regex) and terminates immediately.
rewrite — Pattern-based URI Rewriting
rewrite regex replacement [flag];| Flag | Behaviour |
|---|---|
| (none) | Continue checking remaining rewrite rules |
last | Stop rewriting; re-match location blocks with new URI |
break | Stop rewriting; serve using current location, no re-match |
redirect | Return 302 |
permanent | Return 301 |
# Rewrite /old/ prefix to /new/ (internal, no redirect) rewrite ^/old/(.*)$ /new/$1 last; # 301 redirect with regex capture rewrite ^/blog/(\d+)$ /posts/$1 permanent; # Strip trailing slash (internal) rewrite ^/(.*)/$ /$1 last; # Add .html extension internally rewrite ^(/[^.]+)$ $1.html break;
HTTP → HTTPS
server { listen 80; server_name example.com www.example.com; return 301 https://$host$request_uri; }
www → non-www (and vice versa)
# www → bare domain server { listen 80; listen 443 ssl; server_name www.example.com; return 301 $scheme://example.com$request_uri; } # bare → www server { listen 80; server_name example.com; return 301 $scheme://www.example.com$request_uri; }
if — Use Sparingly
Avoid
ifinsidelocationblocks — it's poorly specified and causes surprises. Safe uses:ifinservercontext, or checking$request_method.
# Safe: server context only server { if ($host = www.example.com) { return 301 https://example.com$request_uri; } } # Safe: check request method location /api/ { if ($request_method = OPTIONS) { add_header Access-Control-Allow-Origin "*"; return 204; } proxy_pass http://backend; } # Avoid: if inside location with proxy_pass (use map or try_files instead)
map — Cleaner Conditionals
http { # Map old paths to new paths map $uri $new_uri { /old-page /new-page; /legacy/about /about; default ""; } server { if ($new_uri) { return 301 $new_uri; } } }
Removing Query String on Redirect
# $uri has no query string; $request_uri does return 301 https://example.com$uri; # Drops query string return 301 https://example.com$request_uri; # Preserves query string
Redirect Table Pattern (many URLs)
http { map $request_uri $redirect_url { /products /shop; /about-us /about; /contact-us /contact; default ""; } server { if ($redirect_url) { return 301 $redirect_url; } } }
Rewrite Logging (Debug)
# In the http or server block rewrite_log on; error_log /var/log/nginx/rewrite.log notice;
Shows each rewrite step at notice level — disable in production.
Regex Reference
| Pattern | Matches |
|---|---|
^/path | URI starting with /path |
/path$ | URI ending with /path |
^/path/(.*)$ | Captures everything after /path/ |
\.(jpg|png|gif)$ | Common image extensions |
[0-9]+ | One or more digits |
[^/]+ | One path segment (no slashes) |
Capture groups are referenced as $1, $2, etc. in the replacement string.