3

I'm trying to achieve something with nginx and redirect rules which seems like it should be pretty straightforward, but I've run into a stumbling block.

Having had a look through many questions and answers, I can't seem to find a solution that works for me.

What I want to achieve is the following:

If someone navigates to my website with any of the following URLs:

http://mywebsite.com
http://mywebsite.com/
http://mywebsite.com/foo

the person will be re-directed to:

http://mywebsite.com/en/
http://mywebsite.com/en/
http://mywebsite.com/en/foo/

This is what I have in my nginx configuration file so far in the order in which I have them in the file:

location ^/en/(.*) {
    try_files $uri /index.php$is_args$args last;
}

location / {
    if ( $uri !~ ^/(index\.php|css|jpg|png|images|core|uploads|js|robots\.txt|favicon\.ico) ) {
        return 301 /en/$uri;
    }
}

However, with the above configuration, I am running into an infinite redirect loop and the URL in the address bar ends up like this before the server gives up:

http://mywebsite.com/en//en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/en/

Can someone please:

a) Explain to me why my configuration has not had the intended effect so I can understand it and not repeat the same errors in the future

b) Propose a solution that works and if possible improve upon my configuration

c) If possible, take it further and explain with examples how I can get nginx to automatically determine the locale associated with the request and dynamically transform the request to include it in the fashion described above.

Thanks

4

Explain to me why my configuration has not had the intended effect so I can understand it and not repeat the same errors in the future

location ^/en/(.*) is not a valid directive.

You might have been confused with location ^~ /en/(.*). This matches any query beginning with /en/ followed by anything.

Actually, request always match the location / directive so that it brings you into an infinite loop.

Propose a solution that works and if possible improve upon my configuration

Just use the Path prefix within the location directive :

location /en/ {
   try_files $uri $uri/ =404;
}

location / {
   return 301 /en$uri;
}
3
  • @krisFR, Thanks for the feedback, much appreciated. However, there is a problem when using your solution, an extra slash is added to the URL, so the URL always ends up like: /en//foo, /en// etc.. I have tried a few modifications to see if it would help but with no luck. – newbie Jun 15 '15 at 19:27
  • @newbie Right, ok solved using return 301 /en$uri instead of return 301 /en/$uri – krisFR Jun 15 '15 at 22:06
  • great that worked a treat. I could have sworn I tried that but maybe my browser was caching the previous responses. I guess I'll have to figure out point c) on my own. ;) thanks for your help, much appreciated! – newbie Jun 16 '15 at 20:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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