Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

138
Views
conditional nginx rewrite rule that exclude redirecting to www if www is already in request

I am using nginx for managing multiple domains for reverse proxy.

I want to redirect all http request to https

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 301 https://$host$request_uri;
}

However, I am not sure how can I make it work for rewriting non www requests to redirect to www in generic way excluding rewriting those requests that already has www in requests as if I just modify below rule it creates problem when someone write as www.domain.com it rewrite to www.www.domain.com

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 301 https://www.$host$request_uri;
}

Please check this image to understand the issue. redirecting to www.www.domain

So I need to have some condition that handles that.

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Please try this

 server {
        listen 80;
        listen [::]:80;
        server_name yourdomain.com www.yourdomain.com me.yourdomain.com;
        return 301 https://yourdomain.com$request_uri;
       }

this will rewrite all 3 domains to https://yourdomain.com

I am not sure about my answer. I am not able to test this now. please try this and comment back

over 4 years ago · Santiago Trujillo Report

0

If you want a generic approach, you can use map directive (should be placed outside the server block):

map $host $basename {
    ~^www\.(.+)  $1;
    default      $host;
}
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 301 https://$basename$request_uri;
}

Update 1

It's look I misread your question (you need to redirect example.com to www.example.com but my answer does an opposite thing), please try the following:

map $host $basename {
    ~^www\.(.+)  $host;
    default      www.$host;
}
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 301 https://$basename$request_uri;
}

Update 2

OP asks an additional question:

Is there a way to exclude specific sub domain like static.example.com which I don't want to rewrite to www.static.example.com?

Yes, rewrite of static subdomain can be prevented with the following map block:

map $host $basename {
    ~^(?:www|static)\..+  $host;
    default               www.$host;
}

If you want to prevent rewrite of any three-component domain name, you can use

map $host $basename {
    ~[^.]+\.[^.]+\.[^.]+  $host;
    default               www.$host;
}
over 4 years ago · Santiago Trujillo Report

0

Non-www to www & https redirect

If I understand correctly, then you want to force non www to www. And you want to force all requests to https. This config code checks if the $host start with "www." or not. If it does not, then nginx will add "www." before the $host then return the correct https location. It will work with subdomains as well.

server {
  if ($host !~* ^www\.) {
    # if host name starts with (case insensitive) "www."
    return 301 https://www.$host$request_uri;
  }
  if ($host ~* ^www\. ) {
    # if host name doesn't start with (case insensitive) "www."
    return 301 https://$host$request_uri;
  }
  listen 80 default_server;
  listen [::]:80 default_server;
  server_name _;
  return 404;
}

Possibly better way with Certbot

You can automatically produce the code you need by using Certbot. It will also help you manage certificates a lot and automate renewal. But Certbot will not change non-www to www, you'll have to edit auto-generated config to look like the config above. The other difference is that you will be expected to have different config blocks/files per domain, but not sure if necessary. This is what the default config looks like per domain.

server {
  if ($host = www.yourdomain.com) {
    return 301 https://$host$request_uri;
  } # managed by Certbot


  if ($host = yourdomain.com) {
    return 301 https://$host$request_uri;
  } # managed by Certbot


  listen 80;
  listen [::]:80;
  server_name yourdomain.com www.yourdomain.com;
  return 404; # managed by Certbot
}

I think it's best practice to separate the config files for each domain and subdomain and use the default Certbot format until you have understood Nginx more. This way you can disable the redirect of non-www to www very easily. The default code above from Certbot, would be what you would put when you don't want to redirect in that case. Long term this makes more sense to me, but I understand when users are more comfortable with www or other parts of the website might need the www.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!