80

I'm sure this has been asked before, but I can't find a solution that works.

A website has switched CMS services, but has the same domain, how do I set up an nginx rewrite for a single page?

E.g.

Old Page

http://sitedomain.co.uk/content/unique-page-name

New page

http://sitedomain.co.uk/new-name/unique-page-name

Please note, I don't want everything within the content page to be redirected, but literally just the url mentioned above. I have about 9 redirects to set up, non of which fit in a pattern.

Thanks!

Edit: I found this solution, which seems to be working, except for the fact that it redirects without a slash:

if ( $request_filename ~ content/unique-page-name/ ) {
   rewrite ^ http://sitedomain.co.uk/new-name/unique-page-name/? permanent;
}

But this redirects to:

http://sitedomain.co.uknew-name/unique-page-name/

5 Answers 5

126

Direct quote from Pitfalls and Common Mistakes: Taxing Rewrites:

By using the return directive we can completely avoid evaluation of regular expression.

Please use return instead of rewrite for permanent redirects. Here's my approach to this use-case...

location = /content/unique-page-name {
  return 301 /new-name/unique-page-name;
}
6
  • 3
    It's definitely more readable. Will this also retain any queries that were on the original URL?
    – SteveEdson
    Oct 25, 2013 at 9:56
  • 1
    Am I right in thinking that using if statements in nginx is bad? Would this still be better practice than using the rewrite method?
    – SteveEdson
    Oct 25, 2013 at 10:10
  • 1
    Using if along with return directive is perfectly fine. See wiki.nginx.org/IfIsEvil . Yes, IMO, it's better than using rewrite. Oct 25, 2013 at 10:22
  • Why return ... instead of rewrite ... ... permanent; for the permanent redirects? Is there a reason why that that should be preferred? In that current answer there's no longer a if statement, was that why? Aug 5, 2020 at 11:30
  • Please see the quoted text in the answer. Aug 6, 2020 at 1:23
29

Ideally you shouldn't use if statements if you can avoid it. Something like this could work (untested).

location ~ /content/(.*)$ {
    rewrite ^ /new-name/$1?$args permanent;
} 
4
  • 1
    Wouldn't that catch everything within the content directory? I only want to redirect the individual item. For example, I have another item in the content directory, but I need it redirecting to .../another-new-name/unique-page-name2
    – SteveEdson
    Oct 25, 2013 at 9:20
  • 1
    I've solved it. Turns out it redirecting correctly, but the script is was hitting was mangling the URL after.
    – SteveEdson
    Oct 25, 2013 at 9:31
  • 1
    Ah, I misunderstood the question. I thought you wanted only the content part to change. The principle remains the same. I'm glad its working for you.
    – Gevious
    Oct 25, 2013 at 9:37
  • 1
    No problem, thanks for the help though, I'll definitely need to use that in the future.
    – SteveEdson
    Oct 25, 2013 at 9:54
17

I used the following solution:

rewrite ^(/content/unique-page-name)(.*)$   http://sitedomain.co.uk/new-name/unique-page-name/$2 permanent;

Works a treat.

0
14

For me it worked without the equals sign like this:

location /old-url {
  return 301 /new-url;
}
2
0

it works for me.

server {
  listen 80;

  location = /content/unique-page-name {
    return 301 http://sitedomain.co.uk/new-name/unique-page-name;
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.