How to redirect non-www to www domain in Nginx
I'm creating a website and would prefer that my users be redirected to the www subdomain. Here's the current behavior:
- http://example.com -> Not working: 404 error
- http://www.example.com -> Working: redirects to https://www.example.com
- https://example.com -> Not working: prompts security risk on some browsers (SSL_ERROR_BAD_CERT_DOMAIN)
- https://www.example/com -> Working: correct URL
How can I get the non-www URLs to successfully redirect to the www URLs?
1 Reply
There's two issues that I'm noticing: the certificate doesn't seem to be configured properly and, like you mentioned, the non-www domain isn't redirecting to the www domain.
TLS/SSL Certificate
First, it sounds as if your TLS/SSL certificate is only for the www URL. This is problematic if a browser ever attempts to navigate to the non-www URL, even if it is just for a brief moment before your server redirects it. You'll likely need to re-create your certificate to function on both the root domain, the www subdomain, and potentially any other subdomains you might need. I usually use a tool called certbot
to automatically generate free Let's Encrypt certificates on my domains. When you run the certbot, a prompt should be presented that allows you to select all available domains (including both the www and non-www domains). Here are some guides that may help you out in more detail:
Secure HTTP Traffic with Certbot
Getting Started with NGINX - Part 3: Enable TLS for HTTPS Connections
Nginx Configuration
Next, you'll need to make sure your Nginx configuration files are configured correctly to redirect the root domain to the www domain. It's possible that there's multiple ways to do this, though I'll describe a method that I've used in the past:
Within the /etc/nginx/conf.d/example.com
file (replacing example.com
with your own domain), you'll want to create three server blocks as shown below. The examples I'm using are barebones (just to demonstrate the redirection) and your configuration file will likely be much different.
Configure a server block that listens on port 80 (http) for both the non-www and www domains. Then, redirect it to the https url of the www domain:
server { listen 80; listen [::]:80; server_name example.com www.example.com; return 301 https://www.example.com$request_uri; }
The second server block should listen on port 443 (https) for the root domain. Then, redirect it to the https url of the www domain.
server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name example.com; return 301 https://www.example.com$request_uri; }
This will be the last and largest server block. It will listen on port 443 (https) for the www domain. This is the correct URL so this server block should be configured to properly display your website.
server { listen 443 ssl http2 default_server; listen [::]:443 ssl http2 default_server; server_name www.example.com; root /var/www/example.com; index index.html; }
There will certainly be additional configuration required and these server blocks might not work as-is. Depending on how you created your TLS/SSL certificate, directives for your certificates may be needed. That said, it's a good starting point and should provide you some guidance on properly redirecting the non-www domain to the www domain. The following guide discuses this in greater detail:
Getting Started with NGINX - Part 4: TLS Deployment Best Practices