I am trying to configure my Nginx to strip out www.
from hostname.
I am looking for generic rule that handle possible subdomain cases.
E.g. If http://www.foo1.sample.com
and http://www.fooX2.sample.com
are two domains.
Then I want to strip any www.
before such subdomains, and redirect them to http://foo1.sample.com
and http://fooX2.sample.com
respectively (WITHOUT knowing the exact subdomain in the rule.)
Thanks.
The best practice, as well as the most efficient way, would be to use a separate server
definition for this.
This will not only ensure that the config is automatically applied to every single one of the websites that are hosted on your nginx instance, but it'll also makes sure that you don't end up running regular expressions on the hostname from multiple instances in your code.
The following is the simplest form:
server {
listen 80;
server_name ~^www\.(?<domain>.+)$;
return 301 $scheme://$domain$request_uri;
}
If you do use https
, then things get more complicated, because you'd have to ensure that the certificates don't mismatch. Unless you have a single certificate for all of your domains, it would be the best practice to simply hardcode everything, as it's already hardcoded in the certificate anyways, and a solution like above simply isn't possible due to the certificate requirements.
Note that the other answer to the question, which uses rewrite ^(.*) http://…$1 …
, is incorrect, and will cause you to lose $query_string
, as well as potentially mangle the encoding of the request as per Nginx pass_proxy subdirectory without url decoding.
If you require an if
-based approach and no hardcoding, neither of which are recommended, e.g., like the other answer, then at least use the correct paradigm, to avoid the bloat and the loss of the $query_string
; note that as per nginx server name regex when "Host" header has a trailing dot, the $host
variable is already normalised by nginx (trailing dot removed, whole thing brought to lower case), so, you don't need to worry about doing a case-insensitive comparison like in the other answer, either:
if ($host ~ ^www\.(?<domain>.+)$) {
return 301 $scheme://$domain$request_uri;
}
I think adding following If block in your Nginx conf file
should work for you. It also takes care of subdomain case you mentioned.
if ($host ~* ^www\.(.*)) {
set $host_without_www $1;
rewrite ^(.*) http://$host_without_www$1 permanent;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With