Websites & apps

Nginx redirects: return vs rewrite, with ready-to-use examples

Write Nginx redirects the right way: when to use return and when rewrite, HTTP to HTTPS, www and non-www, moved pages and folders, bulk redirects with map, and keeping query strings.

IntermediateLinux VPS3 min read

Nginx has no .htaccess, so Nginx redirects go in the server configuration. There are two tools, return and rewrite, and choosing the right one keeps configs fast and readable. This guide shows when to use each and gives tested examples for the redirects every site needs.

Before you start

  • Root access to Nginx and an understanding of server blocks: nginx.conf explained.
  • Use 302 while testing; browsers cache 301s hard. Switch to 301 when correct.

return vs rewrite

returnrewrite
What it doesStops processing and sends a status (and URL)Changes the URI with a regex, then redirects or continues internally
RegexNo (but can use variables)Yes, with capture groups
Speed and clarityFastest, easiest to readSlower, easier to get wrong
Use forAlmost every redirectPattern-based URL changes, internal rewrites

Rule of thumb: use return unless you need regex captures.

HTTP to HTTPS

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 301 https://example.com$request_uri;
}

$request_uri includes the path and query string, so nothing is lost.

www to non-www (or the reverse)

server {
    listen 443 ssl;
    http2 on;
    server_name www.example.com;
    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    return 301 https://example.com$request_uri;
}

A separate server block per hostname is cleaner and faster than if ($host = ...). The certificate must cover www too, or browsers show an error before the redirect happens.

A single moved page

location = /old-page/ { return 301 /new-page/; }

A moved folder, keeping the rest of the path

location ^~ /blog/ {
    rewrite ^/blog/(.*)$ /articles/$1 permanent;
}

permanent sends 301, redirect sends 302. With rewrite, the original query string is appended automatically unless the replacement ends with ?.

A whole domain moved

server {
    listen 443 ssl;
    server_name old-domain.com www.old-domain.com;
    # certificate for old-domain.com
    return 301 https://new-domain.com$request_uri;
}

Hundreds of redirects with map

For site migrations, a map is far faster and tidier than hundreds of locations. In the http context:

map $request_uri $redirect_to {
    default "";
    /old-about/       /about/;
    /products/1234    /shop/blue-widget/;
    ~^/news/(\d+)$    /blog/post-$1/;
    include /etc/nginx/redirects.map;
}

In the server block:

if ($redirect_to) { return 301 $redirect_to; }

if with only a return inside is safe. Lines starting with ~ are regexes. Keep the long list in the included file, one old new; per line.

Remove or add a trailing slash

rewrite ^/(.*)/$ /$1 permanent;

Exclude real directories and the homepage if your app needs them; test carefully, since this rule is a common cause of loops.

Internal rewrites (no redirect)

Without permanent/redirect, rewrite changes the URI internally and the visitor's URL stays the same:

rewrite ^/p/(\d+)$ /product.php?id=$1 last;

last restarts location matching with the new URI; break stays in the current location. For front-controller apps, try_files $uri $uri/ /index.php?$args; is simpler than rewrite rules.

Test redirects

curl -sI http://example.com/old-page/ | grep -iE '^HTTP|^location'

Follow a chain with curl -sIL; aim for a single hop to the final URL.

Troubleshooting

  • Redirect loop: the target matches the same rule, or the app redirects back (e.g. WordPress site URL is www while Nginx forces non-www). See fix redirect loops.
  • Query string doubled: rewrite appends args automatically; end the replacement with ? if you added them yourself.
  • Redirect ignored: another location matched first. Check location matching order.

FAQ: Nginx redirects

Can I convert .htaccess redirects to Nginx?

Yes. Redirect 301 lines become return 301 in locations or a map; RewriteRule becomes rewrite. Review each by hand.

301 or 308?

Both are permanent. 308 keeps the method (POST stays POST); for page redirects 301 is standard.

Do redirects hurt SEO?

A single 301 passes ranking signals. Avoid chains and loops.

Next steps

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.