Nginx Rewrite domain to Subfolder excluding trailing slash - redirect

I am trying to rewrite a domain to include a language path but without the trailing slash.
So
www.example.com => www.example.com/en
www.example.com/page/ => www.example.com/en/page
www.example.com/page => www.example.com/en/page
I am currently using this config, but it is not working as expected.
server {
listen 80;
server_name www.example.com;
root /var/www/example.com/public;
rewrite ^/(.*)/$ /$1 permanent;
index index.php index.html;
location = / {
return 301 http://www.example.com/en$request_uri;
}
}
Mainly,
www.example.com => www.example.com/en/ => www.example.com/en
www.example.com/page => www.example.com/page
This code is also playing havoc on some of the http_post requests.

In the case of a POST, the redirect is downgraded to a GET (this is normal behaviour). The 307 response can be used to repeat a POST with the new URI. See this page for more.
In which case, you will need to rewrite your configuration to use return 307 statements. You can use regular expression location blocks to capture the URI without its trailing /. See this document for more.
One way to identify URIs that do not begin with /en, is to use a location ^~ /en block to process all URIs that do begin with /en, and use the regular expression location block to capture everything else.
For example:
location = / {
return 307 /en;
}
location ~ ^(/.*?)/?$ {
return 307 /en$1;
}
location ^~ /en {
...
}

Related

Add slash to redirect if URL is not ending with slash in Nginx

I wanted to add a slash to a redirect URL because the target (Wordpress) also redirects if the url does not end with a slash. This would result in two redirects.
My current config doesn't seem to work
server {
listen 80;
server_name old.domain.com;
location ~ ^(.*)[/]$ {
return 302 https://new.domain.com/$request_uri;
}
location ~ ^(.*)[^/]$ {
return 302 https://new.domain.com/$request_uri/;
}
}
Try to put url with '/' before without '/', might it matching with first without slash and redirecting it
Try this
server {
listen 80;
server_name old.domain.com;
location ~ ^(.*)[/]$ {
return 302 https://new.domain.com/$request_uri/;
}
location ~ ^(.*)[^/]$ {
return 302 https://new.domain.com/$request_uri;
}

nginx conditional redirects rules

I have such a task:
http://www.realtyadvisorselite.com/homes-for-sale/skokie
to redirect permanently to
http://www.realtyadvisorselite.com/residential/homes-for-sale/skokie
another words add "residential" subfolder if it is missing from url
I have such server blocks in nginx.conf
server {
listen 80;
server_name realtyadvisorselite.com;
return 301 http://www.realtyadvisorselite.com$request_uri;
}
server {
listen 80;
server_name www.realtyadvisorselite.com;
location / {
proxy_pass http://repar;
}
}
Sorry, seems like a simple task but I cannot understand nginx regexp approach... Thank you!
You question implies that it is a single URL that requires redirection. So a simple option is to use an exact match location and a return statement:
location = /homes-for-sale/skokie {
return 301 /residential/homes-for-sale/skokie;
}
If you wanted all URIs that begin with /homes-for-sale to be prefixed with /residential, you could use a prefix location and a return statement:
location ^~ /homes-for-sale/ {
return 301 /residential$request_uri;
}
See this document for more.

NGINX - redirect www.my-domain.com/blog/1234 to blog.my-domain.com/1234

I'm currently using the following location block to redirect all requests from /blog to blog.my-domain.com/:
location ^~ /blog {
rewrite ^ $scheme://blog.dockerhost$request_uri? permanent;
}
However, I would also like to remove the /blog at the end of the URL. Right now www.domain.com/blog/1234 turns into blog.domain.com/blog/1234, when I really want blog.domain.com/1234.
It can be done without a rewrite.
location ~ ^/blog(.*)$ {
return 301 $scheme://blog.dockerhost$1;
}
location ^~ /blog {
rewrite ^/blog(.*) $scheme://blog.dockerhost$1$is_args$args? permanent;
}

Nginx Exclude a query string url from being redirected

I am currently redirecting my root domain to a subfolder. However I want to exclude a query string url which is used for an ajax call (www.example.com/?act=12). I am however unsure of how to do this in nginx.
This is my current nginx config file
server {
listen 80;
server_name example.com;
return 301 http://www.example.com$request_uri;
}
server {
listen 80;
server_name www.example.com;
root /var/www/example.com/public;
index index.php index.html;
location = / {
return 301 http://www.example.com/it/;
}
location / {
proxy_pass http://localhost:8080;
include /etc/nginx/proxy_params;
}
location ~* \.(js|css|jpg|jpeg|gif|png|svg|ico|pdf|html|htm)$ {
expires 30d;
}
location ~ /\.ht {
deny all;
}
}
Any help will be appreciated.
That can be achieved by using the evil if block.
The query string arguments are presented as variables with a $arg_ prefix. If you just need to test that act is set, try this:
location = / {
if ($arg_act) {
rewrite ^ /my/ajax/call last;
}
return 301 http://www.example.com/it/;
}
If you need to test for a specific value of $arg_act use the = operator.
See this document for details.

How to redirect a specific path to the same path without www in nginx

I've encountered an issue during server configuration: I require a 301 redirect from http://www.example.com to http://example.com just for one specific url alias - like /partners.
the expected output- http:// www.example.com/partners/stuff -> http:// example.com/partners/stuff.
I've tried adding the following code to the vhosts already:
server {
server_name http://www.example.com/partners;
return 301 $scheme://example.com/partners;
}
but vhosts gives me an error telling me this code isn't valid.
What's the correct way of implementing such rewrite?
server_name is for domain only. I can suggest you 2 solutions.
Copy configs between servers. This is the best solution recommended by nginx's author.
server {
server_name example.com;
include example.com.conf;
}
server {
server_name www.example.com;
include example.com.conf;
location /partners/ {
return 301 $scheme://example.com$request_uri;
}
}
Or using if. Bad solution due performance
server {
server_name .example.com;
...
location /partners/ {
if ($host = "www.example.com") {
return 301 $scheme://example.com$request_uri;
}
}
}
http://wiki.nginx.org/IfIsEvil
http://wiki.nginx.org/Pitfalls#Server_Name