Table of Contents

NGINX rewriting rule for getting clean URL

NGINX Rewriting for Clean WordPress Permalink Structure When deploying a dynamic application like WordPress behind a reverse proxy, managing the URL structure...

2026-08-10

NGINX Rewriting for Clean WordPress Permalink Structure

When deploying a dynamic application like WordPress behind a reverse proxy, managing the URL structure efficiently at the web server level—using NGINX—is crucial for performance, SEO, and maintainability. A common requirement is cleaning up the permalink structure generated by WordPress to adhere to a cleaner, more semantic format, such as removing the category prefix.

This guide will detail the appropriate NGINX rewrite rules necessary to transform URLs from the traditional WordPress structure (e.g., /category/%category%/%postname%/) to a cleaner structure (e.g., /postname/). We will explore both the traditional rewrite directive and the more modern, robust try_files approach.

Understanding the Problem in Context

WordPress relies on its internal routing mechanism, typically handled by .htaccess files, to interpret permalinks. When NGINX acts as a reverse proxy, it receives the full request path and forwards it to the PHP application. If the application expects clean URLs but receives verbose paths, we must manipulate the path in NGINX before proxying, ensuring the backend application only sees the necessary information.

The goal here is path stripping: removing the category segment when accessing a single post URL.

Method 1: Using the rewrite Directive (Classic Approach)

The rewrite directive allows for complex pattern matching and substitution. This method is effective for simple, specific redirects or path manipulations based on regular expressions.

To strip the category prefix, we need to match the pattern that includes the category slug and remove it from the URI being sent downstream.

server {
      listen 80;
      server_name example.com;
      root /var/www/html;
  
      location / {
          # Rewrite rule to strip the category part if it exists before the post name
          rewrite ^(.*)/([^/]+)/(.+)$ /$3 permanent;
  
          # Proxy pass to the WordPress application
          proxy_pass http://127.0.0.1:8080;
      }
  }
  

Explanation:

In the example above, if the incoming URI is /category/my-category/my-post-name/, the regex ^(.*)/([^/]+)/(.+)$ captures: 1. (.*) as the category path (group 1). 2. ([^/]+) as the category slug (group 2). 3. (.+) as the desired post name (group 3).

The rewrite command then substitutes the entire path with just the content of group 3 ($3), effectively transforming /category/my-category/my-post-name/ into /my-post-name/. Using permanent ensures this is a true URL change.

Method 2: The Modern Approach with try_files (Recommended)

For modern NGINX configurations, especially when dealing with routing and file existence checks—a principle highly valued in robust systems like those found in the Laravel ecosystem—the try_files directive is often superior to complex regular expression rewrites. It handles routing based on file existence more cleanly.

While try_files doesn't perform path substitution directly, it allows us to configure NGINX to serve content from specific locations or handle redirects efficiently before proxying. For a scenario where you are strictly rewriting the URL before passing it to PHP, combining try_files with configuration logic is powerful:

server {
      listen 80;
      server_name example.com;
  
      location / {
          # Attempt to find the requested file directly.
          # If not found, try to rewrite and proxy.
          try_files $uri $uri/ /index.php?$args;
      }
  
      location ~ ^/(.*)/(.+)/$ {
          # This block specifically targets paths that look like category/postname/
          # We use a regex capture group to extract just the postname for proxying.
          rewrite ^/(.*)/([^/]+)/(.+)$ /$3 break; 
      }
  
      proxy_pass http://127.0.0.1:8080;
  }
  

This combined approach uses a specific location block to handle the path transformation explicitly for the known structure, and allows try_files to manage standard file serving paths efficiently. When building high-performance infrastructure, ensuring that routing rules are precise prevents unintended side effects, which aligns with the architectural focus seen in scalable frameworks like those promoted by laravelcompany.com.

Implementation Best Practices

When implementing these changes, always test your configuration thoroughly before deploying. Use NGINX's built-in testing tools to catch syntax errors:

sudo nginx -t
  

After any successful modification, remember to reload the service to apply the new rules:

sudo systemctl reload nginx
  

By carefully defining these rewrite rules in NGINX, you offload routing complexity from your application layer and ensure that all incoming requests are correctly formatted before reaching your dynamic content generator.

Stefan

Stefan

SEO engineer and Laravel developer. Building tools to help Laravel applications rank higher in search results.

Share this article

Back to Blog