Skip to main content
In this lesson we cover Nginx URL redirects (using return) and rewrites (rewrite, try_files) — when to use each, how they behave, and practical examples you can apply during site migrations or reorganizations. Think of URLs like a postal address. If you moved from 111 Main Street, Apt 204 to 555 Meadows Drive, the post office (or senders) must be told where to send new mail. Similarly, redirects tell clients the resource has permanently or temporarily moved (the client is instructed to request a new URL). Rewrites change how the server internally resolves a request so content from a different path is served without telling the client about a new URL. Why this matters:
  • Redirects are ideal when moving content to a new domain or path and you want search engines and clients to update their records.
  • Rewrites are useful when you want to serve the same content under a new, nicer URL without changing what the client sees.

Redirecting to a new domain

Redirects are typically implemented with the return directive. Use 301 for permanent, 302 for temporary.
A flowchart titled "Redirecting to New Domain" showing an NGINX request/redirect flow. It depicts a request to honda.cars.com going through decision boxes and being routed to targets like cars.com, toyota.cars.com, honda.com and bikes.honda.com before returning a response.
Example: redirect all requests for honda.cars.com to cars.honda.com, preserving the full request URI and query string:
You can also redirect HTTP to HTTPS for the same host. Remember HTTPS requires TLS certificates configured on the server block that listens on port 443.
When redirecting HTTP to HTTPS, ensure the server block on port 443 is configured with valid TLS certificate and key files; otherwise clients will fail to connect securely.
Example: redirect HTTP to HTTPS, and the matching HTTPS server block:
Important built-in variables:
  • $host — the host name from the request (for example, honda.cars.com).
  • $request_uri — the full original request URI including query string (for example, /2024/civic-type-r?color=red).
Example transformation:
  • Incoming request: honda.cars.com/2024/civic-type-r
  • With return 301 https://cars.honda.com$request_uri; the client is redirected to: https://cars.honda.com/2024/civic-type-r
You can scope a return inside a location block to redirect a single page rather than the entire domain. Example:

HTTP status codes quick reference

Tip: Inspect status codes and request metadata in your browser Developer Tools → Network tab to see how redirects and rewrites behave in practice.
A screenshot of a browser Developer Tools Network panel listing HTTP requests (GET/POST), domains like google.com, status codes, file types and sizes, with several entries marked "Blocked By uBlock." The slide is titled "Developer Tools" and includes a small "© Copyright KodeKloud" notice.
Each row in the Network panel corresponds to a single resource request and shows method, status code, host, type, size, and response/request headers.

Rewrite rules — when to rewrite vs redirect

Rewrite rules change how the server resolves an incoming URI. Use rewrites when you want to:
  • Keep the visible URL the same while serving content from a different backend path.
  • Provide clean URLs that map to existing files or application routes.
  • Avoid breaking links after reorganizing site structure.
Analogy: notifying the post office to change the package label so items addressed to your old address are delivered to the new address without the sender knowing — an internal relabeling.

Simple rewrite (client-visible redirect)

If you want clients redirected from an old path to a new one (permanently), use rewrite ... permanent or return 301:
This issues a permanent redirect (HTTP 301). If you want the server to internally serve content from another path without redirecting the client, use try_files or an internal rewrite.

Serving images from a new path (example)

Suppose your site files originally store images in pics, but you want them served from /images. You can either rename the folder or rewrite requests from /pics/* to /images/*. Initial tree:
Option 1: client-visible redirect from /pics/... to /images/...:
A request to http://honda.cars.com/pics/type-r.jpg will be redirected to http://honda.cars.com/images/type-r.jpg. Option 2: internal rewrite (serve content from /images without redirecting):
  • Prefer try_files or an internal alias/root configuration for better performance and less client-visible churn.
Why use rewrites:
  • Preserve bookmarks and external links after reorganizing content.
  • Present user-friendly URLs while keeping implementation details hidden.
  • Support incremental migrations without downtime.

Regular expressions (Regex) primer for Nginx

Regex is frequently used in rewrite rules and location match patterns to capture and transform URIs.
The image is a slide titled "Regular Expression 101" with the subtitle "Regex is a sequence of characters that forms a search pattern." Below it are three colorful icons labeled "Search text", "Match text", and "Manipulate text."
Common regex symbols:
  • ^ — start of string
  • $ — end of string
  • . — any single character (except newline)
  • * — 0 or more of the preceding token
  • + — 1 or more of the preceding token
  • ? — 0 or 1 of the preceding token
  • () — capture group
  • [] — character class, e.g., [a-z]
  • | — alternation (logical OR)
  • \d, \w, \s — shorthand for digits, word characters, whitespace (availability may vary by flavor)
Examples — strings and regex matches:
Capturing and reusing parts of a URL: Parentheses capture parts of the matched URI which you can reference in the replacement string as $1, $2, etc. Example:
  • ^/old_page/(.*)$ captures everything after /old_page/ into $1.
  • Replacement /new_page/$1 reuses that captured part.
Regex can be powerful but also complex — test patterns using tools like Regex101 to avoid surprises. Useful link: This concludes the conceptual portion. Next up: demo walkthroughs showing these directives in action.

Watch Video