81

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

128

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
18

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;
  }
}
1
  • Using the full path of return line worked for me. However, in my case I'm using two different domains, so not sure that is relevant. Jan 7 at 14:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .