Lesson 9: URL Rewriting and Redirection Rules
Welcome to Lesson 9! Now that you're comfortable with Nginx fundamentals, reverse proxies, load balancing, and SSL/TLS, it's time to master URL manipulation. URL rewriting and redirection are essential skills for creating clean URLs, handling legacy routes, and implementing SEO-friendly patterns.
Learning Goals:
- Understand the difference between URL rewriting and redirection
- Master the
rewritedirective and regular expressions - Implement various types of HTTP redirections
- Create clean URL patterns for applications
- Handle common URL manipulation scenarios
Understanding URL Rewriting vs. Redirection
Before diving into implementation, let's clarify these two concepts:
- URL Rewriting: Internally changes the request URI without the client's knowledge
- URL Redirection: Sends an HTTP response telling the client to make a new request to a different URL
server {
listen 80;
server_name example.com;
# Redirection - client sees new URL
location /old-page {
return 301 /new-page;
}
# Rewriting - client doesn't see change
location /api/ {
rewrite ^/api/(.*)$ /backend/$1 break;
}
}
The Rewrite Directive
The rewrite directive is your primary tool for URL manipulation. Its syntax is:
rewrite regex replacement [flag];
Common Rewrite Flags
- last: Stops processing and starts a new search for matching location
- break: Stops processing within the current context
- redirect: Returns 302 temporary redirect
- permanent: Returns 301 permanent redirect
server {
listen 80;
server_name mysite.com;
# Remove trailing slashes
rewrite ^/(.*)/$ /$1 permanent;
# Clean URLs for PHP applications
location / {
try_files $uri $uri/ @rewrite;
}
location @rewrite {
rewrite ^/(.*)$ /index.php?q=$1 last;
}
}
Common Redirection Patterns
HTTP to HTTPS Redirection
server {
listen 80;
server_name example.com www.example.com;
# Redirect all HTTP traffic to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name example.com www.example.com;
# SSL configuration from previous lessons
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
# Your main site configuration
root /var/www/html;
index index.html;
}
WWW to Non-WWW (or Vice Versa)
- Non-WWW Preferred
- WWW Preferred
server {
listen 80;
server_name www.example.com;
return 301 http://example.com$request_uri;
}
server {
listen 80;
server_name example.com;
# Main configuration
}
server {
listen 80;
server_name example.com;
return 301 http://www.example.com$request_uri;
}
server {
listen 80;
server_name www.example.com;
# Main configuration
}
Choose one domain version (www or non-www) as your canonical version and stick with it consistently. This helps with SEO and avoids duplicate content issues.
Practical Rewriting Scenarios
RESTful API URL Cleanup
server {
listen 80;
server_name api.company.com;
# Rewrite /users/123 to /users?id=123
location ~ ^/users/([0-9]+)$ {
rewrite ^/users/([0-9]+)$ /users?id=$1 break;
proxy_pass http://backend_api;
}
# Handle nested resources: /users/123/posts/456
location ~ ^/users/([0-9]+)/posts/([0-9]+)$ {
rewrite ^/users/([0-9]+)/posts/([0-9]+)$ /posts?user_id=$1&post_id=$2 break;
proxy_pass http://backend_api;
}
}
File Extension Removal
server {
listen 80;
server_name blog.example.com;
# Remove .html extension
location / {
rewrite ^(/.*)\.html$ $1 permanent;
}
# Internal rewrite to serve .html files without extension
location / {
try_files $uri $uri.html $uri/ =404;
}
}
Legacy URL Migration
server {
listen 80;
server_name store.example.com;
# Redirect old product URLs to new structure
rewrite ^/products\.php\?id=([0-9]+)$ /products/$1 permanent;
# Handle category migrations
rewrite ^/category/electronics/(.*)$ /categories/electronics/$1 permanent;
rewrite ^/category/books/(.*)$ /categories/books/$1 permanent;
# Serve new URL structure
location /products/ {
try_files $uri @product_handler;
}
location @product_handler {
# Your product handling logic
}
}
When implementing permanent redirects (301), be extremely careful. Browsers cache these aggressively, and undoing them can be challenging. Test with temporary redirects (302) first.
Advanced Rewriting with Conditions
Nginx doesn't have if-else statements like programming languages, but you can use the if directive carefully for conditional rewriting.
server {
listen 80;
server_name example.com;
# Redirect based on query parameters
if ($args ~* "^utm_source=newsletter") {
set $args "";
rewrite ^/(.*)$ /tracked/$1? permanent;
}
# Mobile device detection and redirection
set $mobile_rewrite do_not_rewrite;
if ($http_user_agent ~* "(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino") {
set $mobile_rewrite perform_rewrite;
}
if ($mobile_rewrite = perform_rewrite) {
rewrite ^/$ /mobile-home redirect;
}
}
Common Pitfalls
- Infinite Redirect Loops: Caused by redirect rules that match their own results
- Overusing if Directive: The
ifdirective in location context has performance implications - Missing Protocol in Redirects: Always specify
http://orhttps://in absolute redirects - Incorrect Flag Usage: Using
lastwhen you needbreakor vice versa - Regex Complexity: Overly complex regular expressions can impact performance
- Forgetting to Test: Always test redirects with
curl -Ibefore deploying
# This creates infinite redirects
location /admin/ {
rewrite ^/admin/(.*)$ https://example.com/admin/$1 permanent;
}
# Correct approach
server {
listen 80;
server_name example.com;
location /admin/ {
return 301 https://example.com/admin$request_uri;
}
}
Summary
URL rewriting and redirection are powerful tools in your Nginx arsenal. Remember:
- Use
rewritefor internal URL manipulation andreturnfor client-facing redirects - Choose appropriate flags (
last,break,permanent,redirect) based on your needs - Implement proper HTTP to HTTPS and domain normalization redirects
- Test thoroughly to avoid infinite loops and performance issues
- Keep regular expressions simple and efficient
Mastering these techniques will help you create clean, SEO-friendly URLs and handle complex URL migration scenarios with confidence.
Quiz
Nginx URL Rewriting and Redirection
What's the key difference between URL rewriting and redirection?