≡ Menu

7 Nginx Rewrite Rule Examples with Reg-Ex and Flags

Nginx RewriteAbility to change (rewrite) incoming URL into a different URL based on your criteria is an essential feature for any webserver.

Nginx rewrite is very powerful and flexible.

In this tutorial, we’ll explain the following examples on nginx rewrite:

  1. Nginx Rewrite Example Using $1, $2, ..
  2. Creating Controller File Using Nginx Rewrite
  3. Rewrite Break Flag in Location Context
  4. Adding Question Mark to Nginx Rewrite Replacement String
  5. If Context and Rewrite Directive
  6. Nginx Rewrite Flags Examples
  7. Capture Nginx Rewrite Hits in Error Log File


The following is the syntax of nginx rewrite:

rewrite reg-ex replacement [flag];

In the above:

  • rewrite directive is part of the ngx_http_rewrite_module module.
  • reg-ex – This is a PCRE regular expression that you’ll specify here. This will be used to match the incoming request URI.
  • replacement – If the reqeust URI matches the reg-ex, then Nginx will use this replacement string to change the request URI accordingly
  • flag – This will decide whether further process of the rewrite directives is required or not. This is explained in details in one of the examples below.

In nginx, the rewrite directive can be specified inside any one of the following three contexts: server, location, if

1. Nginx Rewrite Example Using $1, $2, ..

The following is an example of Nginx rewrite directive:

rewrite ^(/data/.*)/geek/(\w+)\.?.*$ $1/linux/$2.html last;

For example:

  • url/data/distro/geek/test.php will get rewritten as url/data/distro/linux/test.html
  • In this example, when you call the original URL with test.php from the browser, it will get rewritten based on the above rewrite rule and will serve test.html page from /data/distro/linux/

In the above rewrite rule:

  • $1 and $2 will capture the appropriate strings from the original URL that doesn’t change
  • $1 in the replacement string will match whatever is inside the 1st parenthesis ( ) in the reg-ex. In our example, $1 is /data/
  • Similarly $2 will match whatever is inside the 2nd parenthesis ( ) in the reg-ex. So, $2 is (\w+), which is any word that comes after the /geek/ in the original URL. In our example, $2 is test
  • last – This flag will make sure to stop the search of rewrite directive in the current location or block and use the changed URI (i.e rewritten URI) and look for new location for any further rewrite directives that matches.
  • *$ – This indicates the extension in the original URL. Please note that here, the extension from the original URL will be replaced by .html in the replaced URL by rewrite. So, even though you call .php in the original URL, it will only serve the .html file in the rewritten URL.

While Nginx rewrite rules does similar things like Apache, there are still lot of differences in terms of how you write a rewrite rule in Nginx.

Also, if you are new to Nginx, this might help to understand the basics: Nginx Vs Apache: Nginx Basic Architecture and Scalability

2. Creating Controller File Using Nginx Rewrite

Using rewrite, you can route many incoming original URL to a master controller template that will serve those request.

The following rewrite example explains this.

rewrite ^/linux/(.*)$ /linux.php?distro=$1 last;

In the above example, when you call thegeekstuff.com/linux/centos URL, it will get rewritten using the above rule and it will serve the page with this rewritten URL: thegeekstuff.com/linux.php?distro=centos

As you see above, any URL that has matches the pattern here (i.e /linux/ in the URL) will be served by linux.php, but the last portion in the original incoming URL will be used as an value for the distro argument in the linux.php controller.

So, the above rewrite rule will transform the incoming URL like this:

  • linux/centos becomes linux.php?distro=centos
  • linux/debian becomes linux.php?distro=debian
  • linux/redhat becomes linux.php?distro=redhat
  • etc.

Similar to previous example, we are using $1 in the replacement string to capture anything that is inside the 1st parenthesis ( ) in the reg-ex. In this case, this is the last part of the original incoming URL.

We are also using the last flag here to instruct nginx to stop search for further rewrite directives in the current-block and move-on to the next matching location for further search.

3. Rewrite Break Flag in Location Context

In this example, we’ve placed the rewrite condition inside location directive.

In this example, the location directive is /data/, which also matches the $1 in the replacement string given below.

location /data/ {
    rewrite ^(/data/.*)/geek/(\w+)\.?.*$ $1/linux/$2.html break;
    return  403;
}

This is what would’ve happened if you used “last” flag above:

  • So, if you had “last” as the flag, after the initial rewrite of the URL, Nginx will typically look for the next rewrite directive for the new URL.
  • In that case, Nginx will keep redirecting to the same location data and keep processing the same rewrite rule for maximum of 10 times, and finally it will return the 500 error code.

Since, we don’t want the above behavior, we’ve used “break” as the flag here which will just stop processing the rewrite blocks any further.

To use rewrite directive effectively inside location context, you need to understand the details of how location works: 13 Nginx Location Directive Examples including Regular Expression Modifiers

4. Adding Question Mark to Nginx Rewrite Replacement String

If a replacement string includes the new request arguments, the previous request arguments are appended after them. If you don’t want this behavior, putting a question mark at the end of a replacement string avoids having them appended.

In the following example, in the replacement string portion there is no question mark at the end. i.e No question mark after $1

rewrite ^/linux/(.*)$ /linux.php?distro=$1 last;

In the above example, when the replacement string include the incoming request arguments, then the arguments from the previous request are appended after them.

Some times, you probably don’t want that append to happen. In that case, use ? as shown below.

In the following example, in the replacement string portion of the Nginx rewrite, we’ve added ? at the end. i.e There is a question mark after $1

rewrite ^/linux/(.*)$ /linux.php?distro=$1? last;

In the above example, replacement string include the incoming request arguments, then the arguments from the previous request are NOT appended after them.

5. If Context and Rewrite Directive

The following few examples illustrates that we can use rewrite inside the if directive.

You can do a conditional rewrite based by doing some if condition comparison using variables like $scheme, $http_host, $http_user_agent, etc, as shown below:

if ($scheme = "http") {
  rewrite ^ https://www.thegeekstuff.com$uri permanent;
}

if ($http_host = thegeekstuff.com) {
  rewrite  (.*)  https://www.thegeekstuff.com$1;
}

if ($http_user_agent = MSIE) {
    rewrite ^(.*)$ /pdf/$1 break;
}

Please note that there are better ways to achieve the end-result of the above examples. The above examples are just given to show that we can add rewrite directive inside if statement in the nginx config file.

Please note that you can also set the value of the following two parameters to either on or off in your nginx config file:

server_name_in_redirect on 
port_in_redirect off

6. Nginx Rewrite Flags Examples

The following are the 4 different Nginx Rewrite directive flags that you can use.

last: This flag will stop the processing of the rewrite directives in the current set, and will start at the new location that matches the changed URL.

rewrite ^(/data/.*)/geek/(\w+)\.?.*$ $1/linux/$2.html last;

break: This flag will stop the processing of the rewrite directives in the current set.

rewrite ^(/data/.*)/geek/(\w+)\.?.*$ $1/linux/$2.html break;

redirect: This flag will do a temporary redirection using 302 HTTP code. This is mainly used when the replacement string is not http, or https, or $scheme

permanent: This flag will do a permanent redirection using 301 HTTP code

rewrite ^ https://www.thegeekstuff.com$uri permanent;

7. Capture Nginx Rewrite Hits in Error Log File

By default, anytime Nginx does successful rewrite, it doesn’t log it in the error.log.

Initially when you are writing complex rewrite rules, you really want to make sure that Nginx is doing the rewrite as per your requirement.

For this, you should enable the rewrite log, which will write a log entry anytime nginx does a successful rewrite using any one of the rewrite directive in the configuration file.

For this, use the rewrite_log directive and set it to on.

Add the following two lines to your nginx default.conf:

error_log /var/log/nginx/error.log notice;
rewrite_log on;

In the above:

  • The first line indicates the location of the error_log file where we want to write the rewrite messages. Please note that a rewrite message is of type notice. So, you have to add “note” at the end of this line as shown above.
  • rewrite_log on – This line enables logging of all the directives of ngx_http_rewrite_module modules to the error_log file.

After the above change, you’ll started seeing lines like this which clearly shows which specific rewrite rule was used in translating the incoming URL. This also will show the final translated URL in the log entry.

[notice] 14385#14385: *1 "^(/data/.*)/geek/(\w+)\.?.*$" matches "/data/distro/geek/test", client: 192.168.101.1, server: localhost, request: "GET /data/distro/geek/test HTTP/1.1", host: "192.168.101.10"
[notice] 14385#14385: *1 rewritten data: "/data/distro/linux/test.html", args: "", client: 192.168.101.1, server: localhost, request: "GET /data/distro/geek/test HTTP/1.1", host: "192.168.101.10"

In the above:

  • The 1st line shows two things 1) Incoming URL 2) Rewrite rule used
  • In the 1st line, it shows the incoming URL (i.e the request). In this example, the request is: “GET /data/distro/geek/test”
  • In the 1st line, it also shows the Nginx rewrite rule that matched this incoming request. In this example, the rewrite rule used by nginx is: “^(/data/.*)/geek/(\w+)\.?.*$”
  • In the 2nd line, it shows the rewritten translated URL that was used by Nginx after applying the rewrite rule. In this example, the translated rewritten URL is: /data/distro/linux/test.html
Add your comment

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! – 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book