This episode breaks down URL redirection with return and rewrite, the difference between 301 and 302 statuses, the last break redirect permanent flags, and the try_files pattern for modern SPA routing.

Public URLs don't stay the same forever. Sometimes a website moves to a new domain, a path changes, or a modern framework needs every request to go to a single entry point. This Episode 5 covers rewrite rules, redirects, and URL manipulation in NGINX.
You'll learn when to use return, when to use rewrite, the difference between 301 and 302 statuses, how the last, break, redirect, and permanent flags work, and the try_files pattern that saves every single page application. All of these concepts are among the most frequently used weapons in real-world NGINX configuration.
The return directive stops processing and sends a response directly to the client. It's the most efficient way to do a redirect:
server {
listen 80;
server_name old-example.com;
return 301 https://example.com$request_uri;
}
location = /old-path {
return 301 /new-path;
}return 301 /new-path; sends a 301 status along with a Location header. Since there's no additional processing, return is very fast and easy to predict. Use return for every case that doesn't need regex-based URL manipulation.
rewrite replaces the URL using a regex pattern and redirects the processing:
server {
listen 80;
server_name example.com;
rewrite ^/product/([0-9]+)$ /product.php?id=$1 last;
}rewrite can change the URL multiple times within a single request, making it more flexible but also more error-prone. The practical rule: if return is enough, don't use rewrite.
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
location /maintenance {
return 302 https://example.com/status-page;
}Choose the status carefully. Using 301 when a feature is actually coming back can make browsers cache the wrong redirect for a long time.
The rewrite directive has four flags:
last: stops the current rewrite processing and looks for a newly matching location.break: stops the rewrite processing without searching for a new location.redirect: sends a 302 redirect (only valid when rewrite is in a server or location context).permanent: sends a 301 redirect.server {
listen 80;
server_name example.com;
rewrite ^/blog/(.+)$ /post/$1 permanent;
rewrite ^/post/(.+)$ /post/index.php?slug=$1 break;
}Without a flag, rewrite stops at the next rule in the same context, then evaluates locations. Understand this order so you don't create rewrite loops that cause 500 statuses.
React, Vue, Angular, and Next.js use client-side routing. URLs like /dashboard don't exist as physical files on the server — everything is handled by JavaScript in the browser. Without special configuration, reloading the /dashboard page produces a 404.
The try_files directive tries a list of paths in order, falling back to the last path if all of them fail:
server {
listen 80;
server_name app.example.com;
root /var/www/app/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}The sequence try_files $uri $uri/ /index.html; means: try the file at the exact URI, then try the URI as a directory, and if neither exists, send index.html. This is the standard SPA pattern. For API backends, just add a separate location that forwards requests to the reverse proxy.
A complete picture of using all three in a single server block:
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
root /var/www/app/dist;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://localhost:3000;
}
location = /old-path {
return 301 /new-path;
}
}Notice the division of labor: return for simple redirects, try_files for the SPA, and proxy_pass for the API. Each tool is used where it shines.
Episode 5 completed the battle over URLs: you can choose return for fast, predictable redirects, rewrite for regex manipulation, distinguish 301 from 302, understand the four rewrite flags, and route SPAs with the try_files pattern.
Key takeaways:
return is faster and simpler; rewrite is flexible but complex.last, break, redirect, and permanent flags control the rewrite flow.try_files $uri $uri/ /index.html;.nginx -t.In the next episode we'll discuss NGINX as a reverse proxy — the difference between forward proxy and reverse proxy, the proxy_pass directive, forwarding important headers to the backend, and managing proxy connection timeouts and buffering.