207

How can I redirect mydomain.example and any subdomain *.mydomain.example to www.adifferentdomain.example using Nginx?

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
deb
  • 12,326
  • 21
  • 67
  • 86

8 Answers8

371

server_name supports suffix matches using .mydomain.example syntax:

server {
  server_name .mydomain.example;
  rewrite ^ http://www.adifferentdomain.example$request_uri? permanent;
}

or on any version 0.9.1 or higher:

server {
  server_name .mydomain.example;
  return 301 http://www.adifferentdomain.example$request_uri;
}
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
kolbyjack
  • 17,660
  • 5
  • 48
  • 35
  • 1
    Do I not need to put in a port to listen on? e.g. listen 80. I have multiple domains that I need to redirect to a primary domain, but my server also has multiple virtual servers for various other domains. – Ryan Jan 25 '13 at 22:26
  • 1
    @Ryan The `listen` directive defaults to port 80 when not specified. It's actually a little more complicated than that in general; see the [nginx configuration docs](http://wiki.nginx.org/HttpCoreModule#Directives) for more details. – Yitz Sep 23 '13 at 17:17
  • 3
    What does the `?` achieve at the end? – Dan Dascalescu Jul 04 '14 at 00:26
  • 7
    What's the difference between `rewrite` and `return 301 $scheme://www.adifferentdomain.com$request_uri;` ? – Dan Dascalescu Jul 04 '14 at 00:27
  • 7
    The ? at the end of a rewrite tells nginx not to append the original query string. Since `$request_uri` already has the query string, there's no need to append it again. The `return 301` syntax is newer, and there should be no difference in behavior between the two methods, but when I originally answered this question, many distributions didn't have the required version, so I went with the safer syntax. – kolbyjack Jul 23 '14 at 11:49
  • Is it possible to forward matched subdomains? like redirect `site.com` to `site.org`, `www.site.com` to `www.site.org` and `test.site.com` to `test.site.org`? – MarSoft Jun 20 '15 at 22:13
  • For the `return 301` option, I do need a question mark at the end? Also, will `http://www.adifferentdomain.com$request_uri` include the variations of the `adifferentdomain` that do not include "www"? – PKHunter Aug 09 '15 at 04:38
  • @kolbyjack can you have a look [here](http://stackoverflow.com/questions/33709219/ngnix-always-listening-to-port-80-by-default) – Saras Arya Nov 14 '15 at 16:07
  • Nice answer. I used this technique for creating an SEO redirect from mydomain.com to www.mydomain.com. – entpnerd Dec 01 '15 at 15:45
  • Since I had a bunch of ssl vhosts on the machine I had to add `listen 443 ssl;` for this to work instead of just pointing to the first returned vhost under a misleading domain. – notbrain Aug 16 '17 at 19:49
  • 1
    For those who don't what the redirect be permanent, should use `302` code. A `301` redirect means that the page has permanently moved to a new location, while `302` redirect means that the move is only temporary. – Majid Dec 08 '19 at 15:02
  • will this work for web pages server or also for backend servers? I mean because the status code ```301 | 302``` – Carlos.V Jul 17 '20 at 14:26
  • seems that the https version (port 443) is not redirecting. any ideas? – RZKY Nov 17 '21 at 08:24
  • note, that `return 301` is not working properly with any request method rather than GET. Most of the clients after getting redirecting response make a new request with GET, but not with an original method. – Dmitry Feb 28 '23 at 14:30
34
server {
    server_name .mydomain.example;
    return 301 http://www.adifferentdomain.example$request_uri;
}

http://wiki.nginx.org/HttpRewriteModule#return

and

http://wiki.nginx.org/Pitfalls#Taxing_Rewrites

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
19

Why use the rewrite module if you can do return? Technically speaking, return is part of the rewrite module as you can read here but this snippet is easier to read imho.

server {
    server_name  .domain.com;

    return 302 $scheme://forwarded-domain.com;
}

You can also give it a 301 redirect.

Robin van Baalen
  • 3,632
  • 2
  • 21
  • 35
  • 1
    Will this keep the path and query params as well? – mpen Dec 30 '14 at 21:56
  • 4
    No this example does not do that @Mark. But I suppose you can mix up the previous answers to come up with something like this: `return 302 $scheme://forwarded-domain.com$request_uri;` – Robin van Baalen Jan 05 '15 at 15:12
  • On a side note, in many cases, you should probably just redirect to https instead of preserving the scheme (ie use https instead of $scheme). This is for the same reasons protocol-relative links are now considered deprecated - http://www.paulirish.com/2010/the-protocol-relative-url/ – mahemoff Apr 29 '15 at 08:36
  • @mahemoff That's not entirely true. Consider the case of having the webserver behind a loadbalancer that's discharging ssl. – Sebastian Neira Sep 22 '16 at 08:13
19

I'm using this code for my sites

server {
        listen 80;
        listen 443;
        server_name  .domain.example;

        return 301 $scheme://newdomain.example$request_uri;
}
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Tech
  • 734
  • 1
  • 6
  • 20
13

That should work via HTTPRewriteModule.

Example rewrite from www.example.com to example.com:

server {
    server_name www.example.com;
    rewrite ^ http://example.com$request_uri? permanent;
}
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
udo
  • 1,486
  • 13
  • 18
  • that's just redirecting www.example.com to example.com. I want to redirect both to a different domain. Can I do that in one rule? – deb May 18 '11 at 13:12
  • I don't know for sure, but I think that server_name mydomain.com; rewrite www.adifferentdomain.com permanent; } should do it? That should take everything *.mydomain.com? – udo May 18 '11 at 13:25
  • @deb you would just have `server_name example.com www.example.com;`. – citruspi Aug 22 '12 at 16:15
  • The question specifically asks for *any subdomains* to redirect to a *different* domain. This answer answers none of the two (explicitly). – Kissaki Sep 25 '14 at 08:27
  • this is missing the important 301 ! – Sliq May 02 '19 at 11:39
10

If you would like to redirect requests for domain1.example to domain2.example, you could create a server block that looks like this:

server {
    listen 80;
    server_name domain1.example;
    return 301 $scheme://domain2.example$request_uri;
}
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
ZanMax
  • 365
  • 4
  • 13
6

You can simply write a if condition inside server {} block:

server {

    if ($host = mydomain.example) {
        return 301 http://www.adifferentdomain.example;
    }
}
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
cryptoKTM
  • 2,593
  • 22
  • 21
  • You need to be careful using 'if' statements on Nginx ( https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/ ). In this case you can just use 'server_name mydomain.com' instead. – Marty Jun 04 '20 at 01:54
  • if is evil when used in location context, it is safe when used to specify redirect host – cryptoKTM Jun 04 '20 at 08:49
4

Temporary redirect

rewrite ^ http://www.RedirectToThisDomain.example$request_uri? redirect;

Permanent redirect

rewrite ^ http://www.RedirectToThisDomain.example$request_uri? permanent;

In Nginx configuration file for specific site:

server {
    server_name www.example.com;
    rewrite ^ http://www.RedictToThisDomain.example$request_uri? redirect;

}
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Taimoor Changaiz
  • 10,250
  • 4
  • 49
  • 53