Serve different directories under one Nginx subdomain

Map URL prefixes to separate directories with root and alias, handle trailing slashes, and verify single-page application routes.

Best practices
Illustration of server operations and request logs

Define several location blocks inside the subdomain's server block. Use root when the directory tree mirrors the URL path; use alias when a URL prefix must map to a differently named directory.

Map two prefixes and a default site

server {
    listen 80;
    server_name sub.example.com;

    location = /location1 { return 301 /location1/$is_args$args; }
    location /location1/ {
        root /var/www/subdomain;
        index index.html;
    }

    location = /location2 { return 301 /location2/$is_args$args; }
    location /location2/ {
        alias /var/www/second-site/;
        index index.html;
    }

    location / {
        root /var/www/subdomain/main;
        index index.html;
    }
}

The explicit redirects normalize the directory entry points and retain query arguments. /location1/style.css maps to /var/www/subdomain/location1/style.css; /location2/style.css maps to /var/www/second-site/style.css.

Understand the filesystem mapping

Directive inside location /location1/ Requested URI File
root /var/www/subdomain; /location1/style.css /var/www/subdomain/location1/style.css
alias /var/www/first-site/; /location1/style.css /var/www/first-site/style.css

root appends the URI. alias replaces the matched location prefix. Pair directory locations ending in / with an alias ending in / so the remaining filename joins correctly.

Add an SPA fallback deliberately

For an application stored under /var/www/frontend/app/, a root-based mapping is straightforward:

location = /app { return 301 /app/$is_args$args; }
location /app/ {
    root /var/www/frontend;
    try_files $uri $uri/ /app/index.html;
}

Ensure /var/www/frontend/app/index.html exists and build the frontend with /app/ as its asset base. Missing assets should generally return 404 rather than HTML; give asset paths a separate location if needed. Avoid copying an alias plus try_files recipe without testing its internal-redirect behavior.

A plain prefix /app also matches /application. Splitting the exact entry path and /app/ avoids that accidental match. Workers need directory traversal permission and read access to the selected files.

Verify every mapping

sudo nginx -t && sudo systemctl reload nginx
curl -I http://sub.example.com/location1/
curl -I http://sub.example.com/location2/style.css
sudo tail -f /var/log/nginx/error.log

Test each index, a real asset, and a missing path. An open() ... failed entry can show the filesystem path Nginx tried, unless missing-file logging is disabled.

FAQ

Which location wins?

An exact = match terminates the search. Nginx remembers the longest prefix, then normally checks regular expressions in configuration order; the first matching regex wins. A longest prefix marked ^~ suppresses that regex check at the relevant level. Nested locations require additional care. See location matching.

Can two URLs expose the same directory?

Yes. Check that both routes should expose that content and that application links and access restrictions remain consistent.

Does alias always need a trailing slash?

It must match the mapping you intend. For directory-prefix mappings such as /location2/, using matching trailing slashes prevents filenames being joined directly to the directory name.

Reference: root and alias.

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting