How to Configure Nginx Redirects for Specific URLs Without Pattern Matching


4 views

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;
}
  1. Missing protocol delimiter (colon after http) creates malformed URLs
  2. 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:

  1. Reload Nginx: sudo nginx -s reload
  2. Test with curl: curl -I http://sitedomain.co.uk/content/unique-page-name
  3. Verify the Location header shows the correct destination
  4. 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/;
}