When migrating between CMS platforms, one common pain point is handling legacy URLs that don't follow predictable patterns. Unlike bulk redirects using regex patterns, individual URL redirects require precise configuration to avoid unintended consequences.
The attempted solution using if
with regex matching has two critical issues:
if ( $request_filename ~ content/unique-page-name/ ) {
rewrite ^ http://sitedomain.co.uk/new-name/unique-page-name/? permanent;
}
- Missing protocol delimiter (colon after http) creates malformed URLs
if
context in Nginx has well-documented performance implications
For precise single-URL redirects in Nginx, use location blocks with exact matching:
location = /content/unique-page-name {
return 301 $scheme://$host/new-name/unique-page-name/;
}
For your 9 distinct redirects, create separate location blocks:
# Redirect set 1
location = /content/unique-page-name {
return 301 $scheme://$host/new-name/unique-page-name/;
}
# Redirect set 2
location = /content/another-page {
return 301 $scheme://$host/different-path/page-name/;
}
For large-scale implementations, consider:
- Using map directive for maintainability
- Adding trailing slash normalization
- Implementing cache control headers
Here's a production-ready configuration snippet:
server {
listen 80;
server_name sitedomain.co.uk;
# Single exact-match redirect
location = /content/unique-page-name {
return 301 https://$host/new-name/unique-page-name/;
}
# Alternative with query string preservation
location = /content/legacy-page {
return 301 https://$host/new-path/page$is_args$args;
}
}
When migrating CMS platforms while keeping the same domain, we often need to set up surgical redirects for specific URLs without affecting other paths. The key requirement is handling exact URL matches rather than pattern-based redirects.
The most reliable approach uses Nginx's location
directive with exact match modifier (=
):
location = /content/unique-page-name {
return 301 http://sitedomain.co.uk/new-name/unique-page-name/;
}
For your case with 9 distinct redirects, we can chain them in the server block:
server {
# Other server configuration...
location = /content/unique-page-name {
return 301 http://sitedomain.co.uk/new-name/unique-page-name/;
}
location = /content/second-page {
return 301 http://sitedomain.co.uk/articles/second-page/;
}
location = /content/third-example {
return 301 http://sitedomain.co.uk/blog/third-example/;
}
# Additional redirects...
}
The exact match (=
) location blocks provide several advantages:
- No trailing slash issues (avoids the problem in your original attempt)
- Better performance than regex matching
- Explicit control over each redirect
- Clear configuration that's easy to maintain
After implementing:
- Reload Nginx:
sudo nginx -s reload
- Test with curl:
curl -I http://sitedomain.co.uk/content/unique-page-name
- Verify the Location header shows the correct destination
- Check for proper trailing slash handling
If you need to handle both trailing slash and non-trailing slash versions:
location = /content/unique-page-name {
return 301 http://sitedomain.co.uk/new-name/unique-page-name/;
}
location = /content/unique-page-name/ {
return 301 http://sitedomain.co.uk/new-name/unique-page-name/;
}