htaccess Redirect Rules: 301, www, Force HTTPS
You opened this page mid-task, not mid-lecture. Below are working .htaccess redirect blocks you can paste into the root of your Apache document root right now: force HTTPS, www to non-www (and the reverse), a single-page 301, trailing-slash normalization, and one combined canonical block. Every flag is explained in a line, so you know exactly what you are pasting. All of these rely on mod_rewrite being enabled and on your .htaccess being read, which requires AllowOverride All (or at least FileInfo) in your Apache vhost or main config.
Read this first: the redirect loop that wrecks your afternoon
The single most common failure with these rules is not a typo in a RewriteCond. It is a redirect loop caused by something else in your stack also redirecting. If you put a host running behind Cloudflare, a CDN, a load balancer, or a reverse proxy in front of Apache, that layer often terminates TLS and forwards plain HTTP to your origin. Your "force HTTPS" rule then sees HTTP, redirects to HTTPS, the proxy strips it back to HTTP at the origin, and the browser bounces forever until you get ERR_TOO_MANY_REDIRECTS.
The fix is to stop trusting %{HTTPS} and trust the proxy's forwarded header instead. Most proxies set X-Forwarded-Proto: https. Redirect only when that header is absent or not https:
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Second footgun: CNAME at the apex. DNS does not allow a real CNAME record on the bare/apex domain (example.com with no subdomain) because the apex must also carry SOA and NS records, and a CNAME forbids any sibling records at the same name (RFC 1034, section 3.6.2). That is precisely why so many people redirect the apex to www rather than the other way around: www is a subdomain and can be a plain CNAME. If your host offers "CNAME flattening" or "ALIAS/ANAME," it works around this, but vanilla DNS does not. Pick your canonical host with that constraint in mind before you write a single rule.
Force HTTPS
Standard, no-proxy version. Redirect every plain HTTP request to the HTTPS equivalent:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTPS} off— only act when the connection is not already encrypted.%{HTTP_HOST}preserves whatever host the visitor used;%{REQUEST_URI}preserves the path and query.L— last rule; stop processing further rules in this pass.R=301— permanent redirect, which browsers and search engines cache. UseR=302while testing so a mistake is not cached.
www to non-www (301)
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [L,R=301]
^www\.(.+)$captures everything afterwww.into backreference%1so this rule works for any domain, no hardcoding.NC— case-insensitive match, soWWW.is caught too.
non-www to www (301)
The reverse. Use this one if you chose www as canonical (often forced on you by the apex-CNAME limitation above):
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
The !^www\. negation means "host does not already start with www," which prevents this from looping on itself.
Single-page 301 and trailing slashes
To send one old URL to one new URL, the cleanest tool is Redirect from mod_alias rather than a rewrite, because it is simpler and order-independent:
Redirect 301 /old-page.html /new-page
If you need pattern matching (regex), use RedirectMatch or a RewriteRule. To add a trailing slash to directory-style URLs without breaking real files:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+[^/])$ /$1/ [L,R=301]
!-f— only redirect when the request does not map to an existing file, sostyle.cssis left alone.NE(not shown here, add it if your URLs contain encoded characters) — "no escape," stops Apache from re-encoding things like%23in the redirected Location.
The combined canonical block
One block to enforce HTTPS and non-www in a single 301 hop, which avoids a double redirect (HTTP→HTTPS then www→non-www) that wastes a round trip and dilutes link equity. Order the conditions with OR so either problem triggers the same canonical rewrite:
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\. [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [L,R=301]
OR— by default stacked conditions are ANDed;ORmakes the rule fire if the request is either insecure or on the www host.- The target host is hardcoded here on purpose: a combined canonical rule has one true home, so you want the exact final host, not a backreference.
Pair the redirect with HSTS only after you have confirmed HTTPS works site-wide, because HSTS is sticky in browsers and hard to undo. See our HTTPS mixed-content fix guide if assets still load over HTTP after the redirect, and what HTTPS actually does for the underlying handshake.
Order, testing, and validation
Rules run top to bottom. Put canonical host/scheme redirects first, content rewrites after. The L flag matters: without it, a later rule can clobber the redirect you just set. Test with curl -I https://www.example.com/old-page and read the Location header and status code directly. You want exactly one 301 hop to the final canonical URL, never a chain of two or three. After you settle the rules, confirm search engines see the canonical you intend with our canonical URL checker.
If you would rather not hand-write the block, generate and verify it with our Apache .htaccess generator: tick force HTTPS, drop or add www, set the status code, and add single-page 301s, then use its redirect checker to trace each hop and catch loops before they hit production.
Frequently Asked Questions
Almost always because something else also redirects. If Cloudflare, a CDN, or a load balancer terminates TLS and forwards plain HTTP to Apache, your %{HTTPS} off rule keeps firing. Trust the proxy header instead: redirect only when %{HTTP:X-Forwarded-Proto} is not https, so the origin stops looping.
Either is fine for SEO as long as you pick one and stay consistent. The technical tiebreaker is DNS: you cannot put a real CNAME on the apex domain (RFC 1034), so if your host lacks CNAME flattening, redirecting non-www to www is often easier to configure at the DNS layer.
R=301 is a permanent redirect that browsers and search engines cache aggressively and use to transfer ranking signals. R=302 is temporary and is not cached the same way. Use 302 while testing so a mistaken redirect is not cached, then switch to 301 once the rule is confirmed correct.
A trailing-slash or canonical rule that matches its own output will loop. Guard it: add RewriteCond %{REQUEST_FILENAME} !-f to skip real files, use the !^www\. negation so a www rule does not re-match www hosts, and always include the L flag so a later rule does not re-trigger the redirect.
No. Apache reads .htaccess on every request, so changes take effect immediately with no restart. That convenience costs a small per-request performance hit. For best performance, move the rules into the main server or vhost config and disable .htaccess with AllowOverride None, which does require a reload.