Proxies·7 min read·

Path-Based Routing and Rewrite Rules in Nginx

Route requests by URL prefix to separate backends and rewrite paths cleanly with Nginx, without leaking internal URLs or breaking deep links.

NB

Netbay Developer Relations

Netbay Engineering

On this page

Host-based routing answers which domain; path-based routing answers which part of that domain. The pattern is everywhere: /api/* goes to the backend service, everything else goes to the frontend, /admin disappears behind a deny, and a legacy path gets rewritten into a modern one. Nginx makes this work through location blocks and two subtly different tools for changing URLs: rewrite and proxy_pass path handling.

Location blocks choose the destination

Nginx evaluates location blocks in a specific order: exact matches and plain prefixes first, regex in order of appearance, and the longest prefix among equals. The practical upshot is that you can carve a domain into paths without any ambiguity.

nginx
server {
    listen 80;
    server_name app.example.com;

    location /api/ {
        proxy_pass http://127.0.0.1:3000;
    }

    location /assets/ {
        proxy_pass http://127.0.0.1:3000;
        expires 30d;
    }

    location / {
        proxy_pass http://127.0.0.1:8080;
    }
}

Here /api/ and /assets/ are separate backends from everything else. The / location at the bottom is the fallback that catches all remaining paths. Note the trailing slashes: a prefix without one also matches the exact path, while the trailing slash version restricts itself to the subtree, which is the cleaner mental model.

How proxy_pass treats the path

The one rule that confuses everyone: if proxy_pass includes a URI, Nginx replaces the matched location prefix with that URI.

nginx
location /app/ {
    proxy_pass http://127.0.0.1:3000/;
}

A request for /app/login arrives at the upstream as /login, because the /app/ prefix was replaced by the trailing slash. Keep proxy_pass bare and /app/login arrives untouched. Choose based on whether your backend knows about the /app prefix — most do not, so the replaced form is the one you usually want.

Rewrites change the URL before routing decisions

Use rewrite in a server block to normalize incoming URLs before location matching runs. Typical jobs: forcing trailing slashes, dropping a version segment, or retiring a legacy path.

nginx
server {
    listen 80;
    server_name app.example.com;

    rewrite ^/v1/(.*)$ /$1 break;
    rewrite ^/old/(.*)$ /new/ redirect;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
    }
}

The first rewrite strips the v1 segment from URLs like /v1/users/7 and hands the remaining path to the backend — a cheap way to support an API version without backend awareness. The second returns an HTTP redirect to /new/, which is right for a permanently moved path. The last flag matters: break finishes rewriting and uses the current path; redirect sends the browser somewhere else.

A combined practical example

Put the pieces together for a single-page app with an API and clean route handling.

nginx
server {
    listen 80;
    server_name shop.example.com;

    location /api/ {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /health {
        return 200 "ok";
    }

    location / {
        try_files $uri $uri/ /index.html;
        proxy_pass http://127.0.0.1:8080;
    }
}

The /health endpoint returns immediately from the proxy without touching any backend — the cheapest health check you can deploy. The final location serves index.html for client-side routes, so a deep link like /product/42 renders the app shell instead of a 404, and the API requests still reach the right process.

Path-based routing inside one domain /api/users /product/42 /health Nginx location prefix match rewrites + proxy_pass API :3000 Web :8080 200 "ok" inline

Takeaway

Path routing keeps one domain serving many concerns, and understanding prefix matching plus the proxy_pass path rule removes ninety percent of Nginx confusion. Rewrites are for changing URLs; locations are for changing destinations — use each for its job. A single Netbay VPS can comfortably front a SPA, its API, and a health check with this config at netbayhosts.in.

Keep reading

Follow along on a real VPS

Deploy Linux in under 60 seconds

These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.

Deploy an instance