# Location Matching Rules — Nginx

Source: https://www.skillbyai.com/en/nginx/s-locations

> Predict which location block NGINX chooses for a URI.

## The precedence everybody gets wrong

Within a server, NGINX selects a **location** for the request URI using these rules. **1.** An **exact match** `location = /path` wins immediately. **2.** Otherwise NGINX finds the **longest matching prefix** among plain prefix locations (`location /images/`) and remembers it. If that longest prefix is marked **`^~`**, it is used and regular expressions are **not** checked. **3.** Otherwise NGINX checks **regular-expression locations** (`~` case-sensitive, `~*` case-insensitive) **in the order they appear** in the file; the **first** that matches wins. **4.** If no regex matches, the remembered longest prefix is used. So a regex such as `location ~* \.(png|jpg)$` overrides a longer prefix like `location /images/` unless that prefix uses `^~`. Named locations (`location @fallback`) are not matched directly; they are targets for `try_files` and `error_page`. Keep configurations readable by preferring prefix locations and using regexes sparingly.

## Which location wins?

Comments show the location chosen for each request URI.

```nginx
location = /health           { return 200 "ok\n"; }      # exact
location /                   { proxy_pass http://app; }   # shortest prefix, fallback
location /static/            { root /var/www; }           # prefix
location ^~ /static/vendor/  { root /var/www; expires 30d; }  # prefix, blocks regex
location ~* \.(png|jpg|svg)$ { expires 7d; root /var/www; }  # regex

# /health                   -> = /health
# /static/app.css           -> /static/                 (no regex matches .css)
# /static/logo.png          -> ~* \.(png|jpg|svg)$      (regex beats a plain prefix)
# /static/vendor/icon.svg   -> ^~ /static/vendor/       (^~ stops regex checks)
# /orders/42                -> /
```

## Sorting post by address

An exact address gets hand-delivered first. Otherwise the clerk finds the most specific postcode bin, but a few special rules on the wall (regexes) are checked in order and can redirect the letter, unless the bin is marked "do not reroute" (`^~`).

**Quiz:** A request for /static/logo.png matches `location /static/` and `location ~* \.png$`. Neither uses ^~. Which wins?

- [ ] location /static/, because it is longer
- [x] location ~* \.png$, because regex locations are checked after the prefix and the first matching regex wins
- [ ] Whichever appears first in the file, always
- [ ] Neither; NGINX returns 404

*Answer:* location ~* \.png$, because regex locations are checked after the prefix and the first matching regex wins. A matching regex overrides the longest prefix unless that prefix is marked ^~.
