How to Redirect to Non-WWW & HTTPS with Nginx (Or WWW)

In this tutorial, we will learn how to configure an Nginx server block to redirect all standard HTTP traffic to HTTPS and the non-www version of the site.

 

Prerequisites: you will need sudo access on your server and an SSL cert configured for the domain in question.

 

Step 1

Begin by opening the server block file for your domain in sudo mode.

 

sudo nano /etc/nginx/sites-available/example.com

 

Now configure two server blocks; first will listen for HTTP requests and 301 redirect them to HTTPS. The second will listen for HTTPS requests and redirect to non-www.

 

/etc/nginx/sites-available/example.com
server {

	listen 80;
	listen [::]:80;

	server_name www.example.com example.com;

	return 301 https://example.com$request_uri;

}


server {

	listen 443 ssl;
	listen [::]:443 ssl;

	if ($host = www.example.com) {
		return 301 https://example.com$request_uri;
	}

	ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
	ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot


	server_name www.example.com example.com;

	root /var/www/example.com/public/;


	#rest of server block...

 

Note – using an if statement in Nginx here is safe here because it is not in a location context. Read more about Nginx configuration structure.

 

Redirect to WWW & HTTPS

Let's say you want to redirect all traffic to WWW you could reverse the logic like this:

 

/etc/nginx/sites-available/example.com
server {

	listen 80;
	listen [::]:80;

	server_name www.example.com example.com;

	return 301 https://www.example.com$request_uri;

}


server {

	listen 443 ssl;
	listen [::]:443 ssl;

	if ($host = example.com) {
		return 301 https://www.example.com$request_uri;
	}

	ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
	ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot


	server_name www.example.com example.com;

	root /var/www/example.com/public/;


	#rest of server block...

 

Test the Configuration

Now let's test the changes have no errors:

 

sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

 

Reload Nginx

For the changes to take effect, we will need to reload Nginx using systemctl like this:

 

sudo systemctl reload nginx
nginx