I see the Nginx HttpRewriteModule documentation has an example to rewrite a www-prefixed domain to a non-www-prefixed domain:
if ($host ~* www\\.(.*)) {
set $h
As noted in the Nginx documentation, you should avoid using the if directive in Nginx where possible, because as soon as you have an if
in your configuration your server needs to evaluate every single request to decide whether to match that if
or not.
A better solution would be multiple server directives.
server {
listen 80;
server_name website.com;
return 301 $scheme://www.website.com$request_uri;
}
server {
listen 80;
server_name www.website.com;
...
}
If you're trying to serve an SSL (HTTPS) enabled site, you got more or less three different options.
if
directive.There is also an option to use SNI, but I'm not sure this is fully supported as of now.
if ($host !~* ^www\.) {
rewrite ^(.*)$ http://www.$host$1 permanent;
}
Well I guess I don't really need the outer "if" statement since I'm only checking for domains of the form xxx.xxx anyways. The following works for me, though it's not robust. Let me know if there is a better solution.
if ($host ~* ^([a-z0-9\-]+\.(com|net|org))$) {
set $host_with_www www.$1;
rewrite ^(.*)$ http://$host_with_www$1 permanent;
}
Edit: Added hyphen to the regular expression since it is a valid character in a hostname.
Solution for multiple domains, working on nginx 1.17 for me:
server {
listen 80;
server_name .example.com;
set $host_with_www $host;
if ($host !~* www\.(.*)) {
set $host_with_www www.$host;
}
return 301 https://$host_with_www$request_uri;
}
In this config example additionally rewrites HTTP on HTTPS, if you don't want rewrite — replace https:// with http:// in return
string.
If you want keep protocol — use $scheme
variable.
The nginx documentation cautions against the use of if for rewriting. Please see the link here: http://wiki.nginx.org/Pitfalls#Server_Name
if ($host ~* ^[^.]+\.[^.]+$) {
rewrite ^(.*)$ http://www.$host$1 permanent;
}
It's only possible to get valid hostnames because the request will never make it to your server otherwise, so there's no need to build your own validation logic.