Skip to main content

Nginx Rewrites

Introduction

URL rewriting is a powerful feature in Nginx that allows you to modify incoming request URLs before they're processed. This enables you to create cleaner, more user-friendly URLs, redirect old URLs to new locations, or modify requests before they reach your application.

In this tutorial, we'll explore Nginx's rewrite capabilities in depth, covering:

  • How rewriting works in Nginx
  • The rewrite directive syntax and flags
  • Common use cases and patterns
  • Performance considerations

Understanding URL Rewriting

URL rewriting allows a web server to map one URL to another, changing what the server sees without affecting what the client typed in the browser. This creates a layer of abstraction between the URLs users interact with and your actual application structure.

Why Use Rewrites?

  • SEO and User-Friendliness: Convert complex URLs with query parameters into clean, readable paths
  • Maintenance: Preserve old URLs when restructuring your site
  • Security: Hide implementation details and file extensions
  • Flexibility: Route requests to different applications or handlers based on patterns

The Nginx Rewrite Directive

The primary tool for URL rewriting in Nginx is the rewrite directive:

nginx
rewrite regex replacement [flag];

Let's break down each component:

  • regex: A regular expression pattern to match against the request URI
  • replacement: The string that will replace the matched URI
  • flag (optional): Controls the behavior after the rewrite occurs

Available Flags

  • last: Stops processing the current set of rewrite directives and starts a search for a new location match
  • break: Stops processing the current set of rewrite directives
  • redirect: Returns a temporary redirect (302) with the rewritten URL
  • permanent: Returns a permanent redirect (301) with the rewritten URL

Basic Rewrite Examples

Let's start with some simple examples to understand how rewrites work in practice.

Simple URL Rewrite

nginx
location /api/ {
rewrite ^/api/users/([0-9]+)$ /api/v1/users/$1 break;
proxy_pass http://backend_server;
}

What happens:

  • A request to /api/users/123
  • Gets internally rewritten to /api/v1/users/123
  • The request is then processed according to the location block rules

Redirecting Old URLs to New Ones

nginx
server {
listen 80;
server_name example.com;

# Redirect old product URLs to new structure
rewrite ^/products/([0-9]+)$ /shop/item/$1 permanent;
}

What happens:

  • A request to example.com/products/42
  • Browser receives a 301 (permanent) redirect to example.com/shop/item/42
  • The browser automatically navigates to the new URL

Working with Rewrite Conditions

Often, you'll want to apply rewrites conditionally. Nginx provides the if directive for this purpose:

nginx
server {
listen 80;
server_name example.com;

# Only apply rewrite for mobile devices
if ($http_user_agent ~* mobile) {
rewrite ^/(.*)$ /mobile/$1 last;
}
}

What happens:

  • If the user agent contains "mobile"
  • A request to /about would be rewritten to /mobile/about

Note: The if directive in Nginx has some limitations and potential issues. It's generally better to use location blocks where possible.

Advanced Rewrite Patterns

Let's explore some more complex examples for common use cases.

Creating a Clean URL Structure

nginx
server {
listen 80;
server_name example.com;

# Rewrite /blog/my-post-title to /blog.php?post=my-post-title
location /blog/ {
rewrite ^/blog/(.+)$ /blog.php?post=$1 last;
}
}

Handling File Extensions Transparently

nginx
server {
listen 80;
server_name example.com;

# Hide PHP extensions
location / {
# Rewrite /page to /page.php
if (!-e $request_filename) {
rewrite ^/(.*)$ /$1.php last;
}
}
}

Capturing and Using Multiple Path Segments

nginx
server {
listen 80;
server_name example.com;

# Rewrite /category/subcategory/product-name to /product.php?cat=category&subcat=subcategory&product=product-name
location / {
rewrite ^/([^/]+)/([^/]+)/([^/]+)$ /product.php?cat=$1&subcat=$2&product=$3 last;
}
}

Visualizing Rewrite Flow

Here's a visual representation of how Nginx processes rewrites:

Performance Considerations

Rewrite rules are processed for every request, so it's important to keep them efficient:

  1. Be Specific: Use location blocks to narrow down where rewrites apply
  2. Optimize Regular Expressions: Avoid costly backtracking and capture only what you need
  3. Use try_files When Possible: For simple file existence checks, try_files is more efficient than rewrites
  4. Consider Caching: For frequently accessed URLs, consider using proxy caching

Common Use Cases

Let's explore some real-world applications of Nginx rewrites:

Single Page Application (SPA) Support

nginx
server {
listen 80;
server_name app.example.com;
root /var/www/spa;

location / {
try_files $uri $uri/ /index.html;
}
}

This configuration ensures that all routes in a SPA are properly handled by redirecting non-existent paths back to the main index.html file.

WordPress Pretty URLs

nginx
server {
listen 80;
server_name blog.example.com;
root /var/www/wordpress;

location / {
try_files $uri $uri/ /index.php?$args;
}
}

This setup allows WordPress to handle pretty permalinks by forwarding requests to index.php when the requested file doesn't exist.

API Version Routing

nginx
server {
listen 80;
server_name api.example.com;

# Default to latest API version
location /api/ {
rewrite ^/api/(.*)$ /api/v2/$1 last;
}

# Handle specific API versions
location ~ ^/api/v[0-9]+/ {
proxy_pass http://backend_servers;
}
}

Debugging Rewrite Rules

When your rewrite rules aren't working as expected, Nginx provides debugging tools:

  1. Enable Rewrite Logging:
nginx
server {
# ... other configuration

# Enable rewrite logging
rewrite_log on;
error_log /var/log/nginx/rewrite.log notice;
}
  1. Test with curl:
bash
curl -I http://example.com/test/path

The -I flag shows only the headers, which is useful for checking redirect status codes.

Summary

Nginx rewrites are a powerful tool for manipulating URLs and controlling how requests are processed. We've covered:

  • The basic syntax and operation of the rewrite directive
  • How to use different flags to control rewrite behavior
  • Conditional rewrites using the if directive
  • Common patterns and real-world examples
  • Performance considerations and debugging techniques

With these skills, you can create clean, user-friendly URLs while maintaining flexibility in your application's structure.

Additional Resources

To deepen your understanding of Nginx rewrites:

  1. The official Nginx documentation on rewrite module
  2. Learn more about regular expressions for more powerful matching patterns
  3. Explore the try_files directive as a complement to rewrites

Practice Exercises

  1. Create a rewrite rule that maps /articles/YYYY/MM/title to /article.php?year=YYYY&month=MM&title=title
  2. Implement a rule that redirects HTTP requests to HTTPS with a permanent redirect
  3. Set up a rule that handles both /product/123 and /product/123.html to the same backend resource


If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)