Skip to content

🎯 Location Matching Rules

Matching Priority (Important!)

When a URL request arrives, Nginx searches for a matching location by priority. It's like finding a book in a library — first check the exact call number, then browse by category, and finally look at the recommendation section.

SyntaxMeaningPriorityExample
=Exact match🥇 Highest= /api/v1/users
^~Prefix match (no regex check after match)🥈 Second highest^~ /static/
~Regex match (case-sensitive)🥉 Normal~ .php$
~*Regex match (case-insensitive)🥉 Normal~* .(jpg|png|gif)$
No modifierPrefix matchLowest/api/

Hands-On Example

nginx
server {
    listen 80;
    server_name example.com;

    # Exact match for homepage
    location = / {
        return 200 "This is the homepage";       # 🥇 Highest priority
    }

    # Exact match for favicon
    location = /favicon.ico {
        access_log off;
        return 204;
    }

    # Prefix match for static files (^~ skips regex after match)
    location ^~ /static/ {
        root /var/www;                            # 🥈 Second highest priority
    }

    # Regex match for image files (case-insensitive)
    location ~* \.(jpg|jpeg|png|gif|ico|webp)$ {
        root /var/www/images;                     # 🥉 Regex match
        expires 30d;
    }

    # Regex match for PHP files
    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # Default match (lowest priority)
    location / {
        try_files $uri $uri/ /index.html;
    }
}

Matching Flow Diagram

When a request reaches Nginx, the matching process works like this:

  1. First, check all = exact matches — if matched, use it immediately
  2. Then check all ^~ prefix matches — if matched, use it immediately
  3. Then check ~ and ~* regex matches in order — use the first match
  4. Finally, use the longest prefix-matched non-modified location

💡 Tip: 💡 Debugging trick: if you're unsure which location was matched, add a unique response header in each location block, then check with curl -I http://example.com/path.