Nginx redirect rule has no affect

Viewed 73

Trying to do a simple redirect:

rewrite https://url.example.com(.*) https://example.com/plugins/url permanent;

Anytime url.example.com is hit, I want it to redirect to that specific path.

EDIT:

Will try to explain this better, as I'm trying to redirect to a specific domain from another.

server {
    server_name example.com plugin.example.com;
    root /home/www/example.com/public;
}

I see the location used for redirects such as:

location / {
    try_files $uri $uri/ /index.php?$query_string;
}

But not sure how to use it in my case, which is to change plugin.example.com to example.com/plugin.

For example:

http://plugin.example.com
https://plugin.example.com
https://plugin.example.com/blah
https://plugin.example.com/blah/more

All of these should redirect to:

https://example.com/plugin
3 Answers

If the original URL is https://url.example.com or https://url.example.com/ then the normalized URI used by the rewrite and location directives will be /. The scheme, host name and query string have all been removed.

To perform a permanent redirect to a URL with a different host name:

Using rewrite (see this document for details):

rewrite ^/$ https://example.com/foo permanent;

Or using location and return (see this document for details):

location = / {
    return 301 https://example.com/foo;
}

The second solution is more efficient, as there are no regular expressions to process.

If the original URL includes a query string: The rewrite will append it automatically unless a trailing ? is added. The return will not, but can be added by appending $is_args$args.


If the scheme and host name are unchanged, then both statements can be simplified:

rewrite ^/$ /foo permanent;

Or:

location = / {
    return 301 /foo;
}

Redirect from subdomain to subfolder on main site

Do you require a redirect from a subdomain to a subfolder on the main site?

  • This would be best accomplished by a separate server context, with the appropriate server_name specification.

  • Else, you could also do this with an if statement testing against $host.

  • As already pointed out elsewhere, rewrite directive operates based on $uri, which does not contain the hostname.


server_name-based matching (recommended):

Hardcoded redirect with a limited number of hostnames (recommended):

server {
    server_name     plugin.example.com;
    return  301     $scheme://example.com/plugin$request_uri;
}
server {
    server_name     about.example.com;
    return  301     $scheme://example.com/about$request_uri;
}

Regex-based redirect from any subdomain to the main domain:

server {
    server_name     ~^(?:www\.)?(?<subdomain>.*)\.example\.com$;
    return  301     $scheme://example.com/$subdomain$request_uri;
}

Regex-based redirect from a limited number of subdomain to the main domain:

server {
    server_name     ~^(?:www\.)?(?<subdomain>plugin|about)\.example\.com$;
    return  301     $scheme://example.com/$subdomain$request_uri;
}


if-based:

If-statement-based redirect with hardcoded hostnames:

server {
    server_name     .example.com;
    …
    if ($host = plugin.example.com) {
        return  301     $scheme://example.com/plugin$request_uri;
    }
    if ($host = about.example.com) {
        return  301     $scheme://example.com/about$request_uri;
    }
    …
}

If-statement-based redirect with a regex-based matching:

server {
    server_name     .example.com;
    …
    if ($host ~ ^(?:www\.)?(?<subdomain>plugin|about)\.example\.com$) {
        return  301     $scheme://example.com/$subdomain$request_uri;
    }
    …
}

Please refer to http://nginx.org/r/server_name for more discussion of which option may be best for you.

You can create separate servers for example.com and plugin.example.com. And create redirect inside plugin.example.com server.

server {
    server_name plugin.example.com;
    return 301 https://example.com/plugin;
}

server {
    server_name example.com;
    root /home/www/example.com/public;
}
Related