find a location

If you directly read other people’s Nginx configuration, some symbols might just intimidate you. In this article, I use a summarized table and flow chart to present the Nginx location block in a much more understandable way.

1. What exactly does Nginx Location Block Match Against?

Nginx is trying to match one of the location blocks for the requested URI. For example, for, URI is /x/y/z. Please note that ‘?p=1’ is not part of URI. ‘?’ means whatever after are parameters, and p=1 is the passed parameter.

Nginx processes a URI before it starts to match against the Location Blocks. If there is any percent-encoding in URI, such as ‘%20’ for space, URI is modified back to what it should be. Similarly, Nginx will interpret ‘.’, ‘..’, and ‘//’ before passing to Nginx Location Blocks.

There could be multiple Location Blocks in the configuration. If one or more blocks match, Nginx will use the algorithm described in Section 4 to choose one block and execute the content of that block.

2. Nginx Location Block Syntax

location ([modifier] (prefix_string | re_string) | @name) {
 . . .

There are two types of location blocks. Matched location block to use either a prefix string or regular expression string to match against the requested URI; named location block is merely used as a reference as long with other directives, such as try_files.

3. Matched Location Block Modifiers

I summarize all the modifiers in a table for easy comparison.

ModifierMeaningUsed Before
~case-sensitive matchingregular expression
~*case-insensitive matchingregular expression
^~this prefix string has a higher priority than the regular expressionprefix string
=MUST be an exact match and terminating the matching process immediatelyprefix string
Nginx Location Block Modifiers

4. Matching Process

4.1 Find the Longest Prefix Match

The matching takes place by looking at every prefix string in the order of occurrence. If an exact match ‘=’ is found, the matching process terminates immediately, and the final location block is identified. If no exact match is found, the longest prefix match block is found. If the longest prefix block is marked as ‘^~’, the matching process terminates, and the longest prefix block is identified as the final location block. Otherwise, the longest prefix block match block is remembered.

4.2 Find the First Regular Expression Match

If the matching process is not terminated yet, it’ll continue to match with regular expressions in the order occurrence. A regular expression must be preceded by either ‘~’ or ‘~*’. Otherwise, it’s not redeemed as a regular expression at all. Once it finds the first regular expression match, the matching process terminates, and the first matched regular expression block is identified as the final location block. If no regular expression block matches, the previously remembered longest prefix is returned as the final location block.

Yes, I know reading text is not fun at all. So I drew a nice flow chart.

Nginx Location Block Matching Process
Nginx Location Block Matching Process

5. Some Common Regular Expression

The regular expression is one of the reasons that make reading others’ block configurations not fun. We are not going to elaborate on how regular expression works, as it’ll divert our diccussion. Most of the time, referring to a cheat sheet is enough. Please refer to Dave Child’s regular expression cheat sheet or Rexegg’s cheat sheet.

We’ll go over a few common regular expressions for location blocks. These examples are from Nginx Drupal Recipe, about which we have a nice tutorial – installing Drupal.

location ~ \..*/.*\.php$ {
        return 403;

‘~’ indicates a regular expression and it’s case-sensitive. ‘\’ is the escape character in a regular expression and ‘\.’ just means the dot character. ‘.*’ means 0 or more occurrences of any characters. ‘$’ at the end means it must be the end of the string. Any URI having a ‘.’ before ‘/’, and ‘.php’ at the end will match this regular expression. As a result, these URIs will return a 403 Forbidden Error Code.

location ~ ^/sites/.*/private/ {
        return 403;

‘^’ means must be the start of a string. Any URI string starting with ‘/sites/’ and ‘/private/’ in it will match this regular expression.

location ~ ^/sites/[^/]+/files/.*\.php$ {
        deny all;

‘^’ inside brackets means not; ‘[^/]’ means anything but ‘/’; ‘+’ means one or more ocurrance. A URI starting with ‘/sites/, having one or more non-‘\’ characters before ‘/files/’, and ending with ‘.php’ will match this regular expression. All such URIs are denied access.

location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        try_files $uri @rewrite;
        expires max;
        log_not_found off;

‘~*’ means case-insensitive, which tells either jpg or JPG will match. ‘|’ means or. Any UIR ending with one of the enumerated file extensions will match this regular expression. What inside the block will be honors. Did you see @rewrite? This is the named location we are covering in the next section.

6. Named Location

We can name a location using any fond name we have. You may think the name is just something that other directives can refer to.

location @rewrite {
        rewrite ^ /index.php;

‘rewrite’ is merely the above location block’s name. As a matter of fact, it can be any name you would like to have. Inside the block, the first directive is ‘rewrite’. Its first argument is a regular expression. Since ‘^’ can match any URI, it redirects anything to /index.php.

Let’s take a look at the above jpg location block one more time.

location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
        try_files $uri @rewrite;
        expires max;
        log_not_found off;

For any file request with those extensions, Nginx first is going to try to access the file directly. If it fails, it’ll make use of @rewrite block to redirect the entire URI to index.php.

7. Conclusion

Hopefully, by now you have mastered the Nginx location block. It’s a little complicated and needs some patience to understand it. For further reading, you may refer to the official Nginx location document.

If you have any questions, please leave a comment below.

Leave a Reply

Your email address will not be published. Required fields are marked *