URL rewriting and redirects are fundamental for SEO-friendly URLs, migrating old URL structures, and general site maintenance. This guide covers the essential patterns in both Nginx and Apache.
Redirect vs Rewrite: The Key Distinction
A redirect tells the browser to request a different URL (visible in the address bar, an actual round-trip); a rewrite internally serves different content for a given URL without the browser knowing (URL stays the same in the address bar).
301 vs 302 Redirects
301 (Permanent) — tells search engines and browsers this change is permanent; passes SEO value to the new URL; browsers may cache this redirect.
302 (Temporary) — indicates a temporary change; doesn't pass SEO value the same way; appropriate for genuinely temporary redirects (e.g. maintenance pages).
Basic Redirect in Nginx
location /old-page {
return 301 /new-page;
}
Redirecting an Entire Domain
server {
listen 80;
server_name www.olddomain.com olddomain.com;
return 301 https://newdomain.com$request_uri;
}
Basic Rewrite in Nginx
rewrite ^/old-path/(.*)$ /new-path/$1 last;
Redirect in Apache (.htaccess or VirtualHost)
Redirect 301 /old-page /new-page
Rewrite in Apache with mod_rewrite
RewriteEngine On
RewriteRule ^old-path/(.*)$ /new-path/$1 [R=301,L]
Removing "www" (or Adding It) Consistently
server {
listen 443 ssl;
server_name www.yourdomain.com;
return 301 https://yourdomain.com$request_uri;
}
Pick one canonical form (with or without www) and consistently redirect the other — avoids duplicate content issues and ensures a single, consistent URL structure for SEO purposes.
Creating Clean/Pretty URLs
location /blog {
rewrite ^/blog/([0-9]+)$ /blog.php?id=$1 last;
}
Rewrites a clean URL like /blog/123 internally to the actual script and parameter structure the application expects.
Redirecting HTTP to HTTPS
See HTTP to HTTPS Redirect: Forcing SSL on Nginx & Apache for the dedicated, complete guide to this specific and very common redirect pattern.
Bulk Redirect Mapping (Many Old URLs to New Ones)
map $uri $new_uri {
/old-page-1 /new-page-1;
/old-page-2 /new-page-2;
}
server {
if ($new_uri) {
return 301 $new_uri;
}
}
Useful during a site migration or restructuring with many individual URL changes to track, rather than writing dozens of individual redirect rules.
Testing Redirects
curl -I https://yourdomain.com/old-page
Verify the response shows the expected status code (301/302) and Location header pointing to the correct destination.
Common Errors
Redirect loop ("too many redirects") — usually caused by conflicting redirect rules, or a redirect rule that inadvertently matches its own destination; review rule order and conditions carefully.
Continue Reading
- HTTP to HTTPS Redirect: Forcing SSL on Nginx & Apache
- Common CMS Migration Pitfalls and How to Avoid Them
- How to Fix Common Nginx Errors (502/504/403)
Browse more articles in Web Servers.