Nginx Rewrite Rules Configuration
Master Nginx rewrite rules for URL manipulation including the rewrite vs return directives, regex captures, conditional rewrites, and SEO patterns.
Detailed Explanation
Rewrite rules in Nginx allow you to modify request URIs before they are processed. They are commonly used for URL normalization, permanent redirects during site migrations, and implementing clean URL routing patterns.
rewrite vs return
For simple redirects, always prefer return over rewrite. The return directive is more efficient because it does not require any regular expression evaluation:
# Preferred for simple redirects (faster)
return 301 https://example.com$request_uri;
# Use rewrite only when you need regex captures
rewrite ^/blog/([0-9]+)/(.*)$ /articles/$1-$2 permanent;
Rewrite Syntax
The rewrite directive takes a regex pattern, a replacement string, and an optional flag that controls processing behavior:
rewrite regex replacement [flag];
Available flags and their meanings:
- last: Stops processing the current set of rewrites and restarts location matching with the new URI.
- break: Stops processing rewrites entirely and processes the request within the current location block.
- redirect: Returns a 302 temporary redirect response to the client.
- permanent: Returns a 301 permanent redirect response to the client.
Regex Captures
Use parentheses in the regex pattern to capture portions of the URI and reference them in the replacement string with $1, $2, and so on:
# /products/123/details -> /api/products?id=123&view=details
rewrite ^/products/([0-9]+)/([a-z]+)$ /api/products?id=$1&view=$2 last;
Conditional Rewrites
Use if directives for conditional rewrites, but be aware that if in Nginx has well-documented pitfalls and should be used sparingly with simple conditions only:
# Remove trailing slash from all URLs
rewrite ^/(.*)/$ /$1 permanent;
# Redirect based on user agent
if ($http_user_agent ~* "mobile") {
rewrite ^/(.*)$ /mobile/$1 last;
}
Common Migration Patterns
# Remove .html extension for cleaner URLs
rewrite ^/(.+)\.html$ /$1 permanent;
# Migrate old URL structure to new one
rewrite ^/old-page$ /new-page permanent;
rewrite ^/category/(.*)$ /topics/$1 permanent;
try_files as an Alternative
For many routing use cases, the try_files directive is cleaner and more predictable than rewrite rules:
try_files $uri $uri/ /index.html;
Debugging Rewrites
Enable the rewrite log to trace exactly how Nginx processes your rewrite rules, which is invaluable for debugging complex chains:
error_log /var/log/nginx/error.log notice;
rewrite_log on;
Use Case
You are migrating a website to a new URL structure and need to set up permanent redirects from old URLs to new ones while preserving SEO value and avoiding broken links.