Nginx Cheatsheet

Rewrites and Redirects

Use this Nginx reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

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 return over rewrite for redirects — it's faster (no regex) and terminates immediately.

rewrite — Pattern-based URI Rewriting

rewrite regex replacement [flag];
FlagBehaviour
(none)Continue checking remaining rewrite rules
lastStop rewriting; re-match location blocks with new URI
breakStop rewriting; serve using current location, no re-match
redirectReturn 302
permanentReturn 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 if inside location blocks — it's poorly specified and causes surprises. Safe uses: if in server context, 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

PatternMatches
^/pathURI 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.