Redirect every http:// request to https:// on the same host with one 301 or 308, then add HSTS. Setup for Nginx, Cloudflare, Vercel and Netlify.
LLaunchScaler·Published ·8 min read
An HTTP to HTTPS redirect should send every http:// request to the same host over https:// in a single 301 or 308 hop, keeping the path and query string: http://example.com/pricing?plan=pro goes to https://example.com/pricing?plan=pro, and nowhere else first. Once that works on every hostname, add an HSTS header so browsers stop making the plain HTTP request at all.
Mozilla's HTTP Observatory takes 20 points from a site that does not redirect to HTTPS, and Google treats a permanent redirect as a strong signal about which URL to keep. Most hosts now do the redirect for you; the work is in checking every hostname and keeping the chain short.
What should the HTTP to HTTPS redirect look like?
The first response to any http:// request should be a 301 or 308 whose Location is the same hostname over https://, with the full path and query preserved. If your canonical hostname differs (www versus non-www), change the host in a second hop, after the protocol. Never more than those two.
The order matters because of HSTS. A browser only stores an HSTS policy for a host it has reached over HTTPS, so redirecting http://example.com straight to https://www.example.com means example.com never gets its policy. The Observatory's FAQ spells out the rule:
Redirect path
Observatory verdict
to to
Questions, answered
What people ask about this
01
Should an HTTP to HTTPS redirect be a 301 or a 302?
Permanent: a 301 or a 308. Google treats both as a strong signal that the target should be processed, while a 302 or 307 is only a weak signal. 308 also guarantees the request method is kept, which is why Vercel and Next.js use it.
Incorrect: first hop goes off-host, which prevents HSTS
And the scores its source code assigns to each case:
What the Observatory finds
Modifier
First redirect goes to HTTPS on the same host, final destination HTTPS
0
No redirect to HTTPS at all
-20
Redirects, but the final destination is not HTTPS
-20
Invalid certificate during the redirect
-20
First redirect goes to another HTTP URL, HTTPS only later
-10
First redirect from HTTP goes to HTTPS on a different host
-5
The HSTS preload list has the same requirement: redirect from HTTP to HTTPS on the same host, if you listen on port 80. The HSTS header guide covers the header you add afterwards.
Should the redirect be a 301 or a 308?
Either. Google's crawling documentation treats 308 as equivalent to 301: both are a strong signal that the redirect target should be processed. A 302 or 307 is only a weak signal, and Google's redirects guide says temporary redirects keep the source URL in results, which is the opposite of what you want for a protocol move.
The difference between 301 and 308 is the request method. MDN notes that browsers following the Fetch Standard switch a POST to GET after a 301, and that the method may not change after a 308. For page URLs that never matters, which is why 301 is the usual choice in server configs, including the Nginx and Apache examples in Google's redirects guide. Vercel and Next.js use 308 to be safe for form posts and APIs. The 301 vs 302 vs 307 vs 308 guide covers all four codes.
How do you redirect HTTP to HTTPS in Nginx?
Give port 80 its own server block that does nothing but redirect, and keep the real site in the port 443 block. $host keeps the hostname the visitor asked for and $request_uri keeps the path and query string, so one rule covers every page.
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name www.example.com;
# certificate directives here
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com;
# certificate directives, HSTS and the site itself here
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}
This gives http://www.example.com two hops (protocol, then host) and http://example.com one, which is the pattern the Observatory and the preload list expect. Swap the hostnames if www is your canonical host. Reload with nginx -t && nginx -s reload, then test with curl.
How do you force HTTPS on Cloudflare?
Turn on Always Use HTTPS: in the Cloudflare dashboard, open the SSL/TLS Overview page, make sure the encryption mode is not Off (the option disappears when it is), then go to Edge Certificates and switch on Always Use HTTPS. It redirects every HTTP request for all subdomains and hosts in the zone to HTTPS.
Two warnings from Cloudflare's own docs:
Redirect loops with Flexible mode. In Flexible mode Cloudflare talks to your origin over plain HTTP. If the origin also redirects HTTP to HTTPS, each request bounces between the two until the browser shows ERR_TOO_MANY_REDIRECTS. Either remove the origin's redirect or set the mode to Full or Full (strict), which needs a certificate on the origin. Cloudflare recommends not performing redirects at your origin at all.
Partial HTTPS. If only part of the site supports HTTPS, Cloudflare says not to enable Always Use HTTPS and to use a single redirect rule for the parts that do.
Cloudflare's page does not state which status code Always Use HTTPS returns, so check it with curl -sI http://yourdomain.com after you switch it on.
Do Vercel and Netlify redirect HTTP to HTTPS automatically?
Yes, both do it without configuration. Vercel's docs say its CDN forwards every HTTP request to HTTPS with a 308, and that the redirect "can't be disabled." On Netlify, sites we requested over http:// in September 2026 answered with a 301 to the same host over https://.
What you still configure on each:
The canonical host. Netlify automatically redirects between the apex and www once you set one as the primary domain, but not for other subdomains; you add those with domain-level redirects. On Vercel, each project domain can carry a redirect to another domain with a status code of 301, 302, 307 or 308; pick a permanent one.
HSTS scope. Vercel sends Strict-Transport-Security: max-age=63072000; on custom domains by default, for that host only. Netlify's docs show adding the header yourself in _headers.
Old domains. A previous domain pointed at the project needs its own redirect to the new canonical URL, or it serves a duplicate copy of the site.
The www vs non-www guide covers choosing the canonical host and setting the DNS for it.
How do you avoid a redirect chain between http, www and https?
Keep every variant at most two hops from the final URL, and link only to the final URL yourself. Google's crawlers follow up to 10 redirect hops, so two is safe, but each extra hop adds a round trip for visitors and gives crawlers one more request to make.
The four variants and where each should end up, for a site whose canonical address is https://example.com:
Request
Hops
Final URL
https://example.com/
0
https://example.com/
http://example.com/
1
https://example.com/
https://www.example.com/
1
https://example.com/
http://www.example.com/
2 (to https://www, then to the apex)
https://example.com/
Long chains come from rules stacked in different layers, for example: the CDN upgrades the protocol, the server adds a trailing slash, the app redirects to www, and a plugin redirects to a new slug, giving four hops for one URL. Collapse them so the protocol and host rules run once, at one layer, and send each old path straight to its final URL. The redirect chains and loops guide shows how to map every chain on a site.
What else should point at HTTPS once the redirect is live?
Everything you control. Google prefers HTTPS pages as canonical by default, but its canonicalization docs list the conflicting signals that can make it pick the HTTP version instead: an invalid certificate on the HTTPS page, insecure dependencies other than images, an HTTPS page that redirects to or through HTTP, and an HTTPS page whose canonical tag points at HTTP.
Google also says a bad certificate or an HTTPS to HTTP redirect makes it prefer HTTP "very strongly," and that HSTS cannot override that. So after the redirect is in place:
Change every rel="canonical" tag to the https:// URL.
List only https:// URLs in your XML sitemap and in any hreflang annotations.
Update internal links, navigation and image URLs to https:// or relative paths, so neither visitors nor crawlers go through the redirect.
Make sure the certificate covers every hostname you serve, including www. Google warns against serving a certificate for the wrong host variant.
In Search Console, confirm the HTTPS version is covered by your property. A Domain property includes every subdomain and both protocols; a URL-prefix property covers only the exact protocol and host you entered, so an http:// prefix property will not show your HTTPS pages.
How do you check the HTTP to HTTPS redirect?
Request each variant with curl and read the status line and Location header. -I asks for headers only and -L follows every hop, so you see the whole chain.
The first Location is https:// on the same hostname you requested.
The path and query string survive (/pricing stays /pricing).
The chain ends in a 200 within two hops.
The HTTPS response carries a Strict-Transport-Security header.
A redirect upgrades the page, not the resources on it: an http:// script or image inside an HTTPS page is still blocked or rewritten by the browser, and the mixed content guide shows how to find those.
To test the redirect alongside the rest of your HTTPS setup, run the free scan on LaunchScaler. It needs only your URL and no account, and its free security checks confirm that HTTP redirects to HTTPS on the same host, that HSTS is present and long enough, and that the certificate chain is valid, while its search checks flag redirect chains longer than one hop. They run with 156 checks across 6 of its 7 categories.
Add a server block that listens on port 80 for your hostnames and contains return 301 https://$host$request_uri;. Keep your site configuration, certificate and HSTS header in the separate server block that listens on 443.
03
How do I force HTTPS on Cloudflare?
In the dashboard, open SSL/TLS, then Edge Certificates, and turn on Always Use HTTPS. Your SSL/TLS encryption mode must not be Off, and if it is Flexible, remove any HTTP to HTTPS redirect at your origin or visitors get a redirect loop.
04
Do Vercel and Netlify redirect HTTP to HTTPS automatically?
Yes. Vercel redirects every HTTP request to HTTPS with a 308 and does not let you turn it off. Netlify-hosted sites answered http:// with a 301 to the same host over https:// when checked in September 2026.
05
How do I check my HTTP to HTTPS redirect?
Run curl -sI http://yourdomain.com and confirm the first line is a 301 or 308 and the Location header is https:// on the same hostname. Then run curl -sIL on the www and non-www variants to see every hop.
A Next.js hydration error means server HTML and the first client render differ, so React rebuilds the tree. The causes, the fix for each, and the SEO cost.