If your website runs on an Apache server, which includes a large share of shared hosting and many WordPress sites, the .htaccess file is one of the most powerful SEO tools you have. A few lines can move an old page, consolidate duplicate versions of your domain, or carry years of rankings across to a new domain.
It is also one of the easiest places to break a website. A single typo can trigger a 500 error across every page, and a careless rule can create redirect loops or send thousands of URLs to the homepage.
This guide gives you copy-ready .htaccess rules for the 301 redirects you will actually need, explains what each part does, and walks through a safe process for testing them in 2026.
Key Takeaways
- Use 301 (or 308) for permanent moves; Google treats them as a strong canonical signal.
- Use
Redirectfor simple cases andRewriteRulewhen you need conditions. - In
.htaccess, RewriteRule patterns never start with a slash. - Always add
R=301; without a code, RewriteRule redirects default to 302. - Back up the file, test on staging, and check every redirect resolves in a single hop.
What is .htaccess and when should you use it?
.htaccess is a per-directory configuration file read by the Apache web server (and compatible servers such as LiteSpeed). Rules in the file apply to that folder and everything below it. Nginx does not read it, so if your host runs Nginx, redirects belong in the server configuration instead.
Before editing, decide whether a redirect is actually right. A permanent move or consolidation calls for a 301. A short-term change calls for a 302 or 307; see our comparison of 301 vs 302 redirects. A page that is gone for good with no replacement may be better returning a 404 or 410, as explained in our guide to fixing 404 errors.
“Use permanent redirects when you're sure that the redirect won't be reverted.”
— Google Search Central, Redirects and Google Search
Redirect types at a glance
| Status / method | Type | How Google treats it | Typical use |
|---|---|---|---|
| 301 Moved Permanently | Permanent | Strong signal the target is canonical | Page moves, domain changes, HTTPS |
| 308 Permanent Redirect | Permanent | Same as 301 | Permanent moves that must keep the request method |
| 302 Found / 307 | Temporary | Original URL tends to stay in results | A/B tests, short-term promotions, maintenance |
| Instant meta refresh | Permanent | Interpreted as permanent | Only when server redirects are impossible |
| JavaScript redirect | Permanent | Processed only if rendering succeeds | Last resort |
Step-by-step: add a redirect safely
- Back up the current file. Download
.htaccessand keep a dated copy. - List your redirects. Build a spreadsheet of old URL to new URL. Map each old page to its closest equivalent, not the homepage.
- Choose the method.
Redirectfor simple paths,RewriteRulefor anything conditional. - Place rules carefully. Put redirect rules near the top of the file, before CMS rewrite blocks (for example the WordPress block), so they run first.
- Test on staging first if you have one. Our guide to staging site SEO explains how to keep that environment out of Google.
- Upload and test immediately. Load the site; if you see a 500 error, restore the backup and check for typos. A server error across the site is a 5xx error Google will notice if it lasts.
- Check status codes. Use a header checker or
curl -Ito confirm each old URL returns 301 and lands on a 200 page in one hop. - Update internal links and sitemaps to point directly at the new URLs.
- Monitor Search Console. Watch the Page indexing report and the Crawl Stats report for spikes in errors.
Copy-ready .htaccess redirect rules
Replace example.com and paths with your own. Each block below is independent; you do not need all of them.
1. Redirect a single page
Redirect 301 /old-page/ https://www.example.com/new-page/
The Redirect directive (mod_alias) matches by prefix, and Apache appends any remaining path to the target. That is handy for folders but can surprise you, so keep paths precise.
2. Redirect a whole folder
RedirectMatch 301 ^/blog/(.*)$ https://www.example.com/articles/$1
RedirectMatch uses a regular expression, and $1 inserts whatever (.*) captured.
3. Force HTTPS
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
See our guide to HTTPS and SEO, and fix any mixed content errors once the redirect is live. Some hosts and CDNs terminate SSL before Apache, in which case this condition never matches and you should use the host's HTTPS setting instead.
4. Redirect non-www to www
RewriteEngine On
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]
To go the other way, swap the hostnames. Pick one version and use it consistently in canonicals and sitemaps.
5. Move to a new domain
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?old-domain\.com$ [NC]
RewriteRule ^(.*)$ https://www.new-domain.com/$1 [R=301,L]
A domain move is a full migration, not just a redirect. Follow our website migration checklist and use Search Console's change of address tool.
6. Remove a query string while redirecting
RewriteRule ^search$ /find [QSD,R=301,L]
Apache's QSD flag discards the original query string. Without it, query strings are passed through to the target.
Understanding RewriteRule flags and syntax
| Element | Meaning | Tip |
|---|---|---|
RewriteEngine On | Enables mod_rewrite for this directory | Needed once, above your rules |
RewriteCond | A condition the next rule must meet | Use for hostname, HTTPS or query string checks |
R=301 | External redirect with status 301 | Without a code Apache defaults to 302 |
L | Stop processing this round of rules | Combine with R: [R=301,L] |
NC | Case-insensitive match | Useful for hostnames |
QSD | Discard the query string | Available from Apache 2.4.0 |
END | Stop all further rewrite processing | Helps prevent loops in .htaccess |
“The removed prefix always ends with a slash, meaning the matching occurs against a string which never has a leading slash.”
— Apache HTTP Server documentation, mod_rewrite
That one sentence explains most "my rule does nothing" problems: in .htaccess, write ^old-page$, not ^/old-page$.
Common .htaccess redirect mistakes
- Forgetting the status code.
[R]alone sends a 302. - Leading slashes in RewriteRule patterns. They never match in
.htaccess. - Redirect chains. Old URL to HTTP to HTTPS to www adds hops. Combine rules so every URL reaches its final destination in one step; see our guide to redirect chains.
- Redirect loops. A rule that matches its own target redirects forever. Use conditions or the
ENDflag. - Redirecting everything to the homepage. Sending every old URL to the homepage frustrates visitors and throws away the topical relevance of the old pages.
- Mixing Redirect and RewriteRule for the same URLs. The modules run separately, which makes results hard to predict.
- Editing live without a backup. One typo can take the site down; keep a copy you can restore in seconds.
- Malformed requests. Badly encoded target URLs can trigger a 400 Bad Request error; test unusual characters carefully.
Related Guides
- 400 Bad Request Error: Causes and How to Fix It
- Crawlability Issues: How to Find and Fix What Blocks Google
- Website Downtime and SEO: How to Monitor and Protect Rankings
Frequently Asked Questions
Where is the .htaccess file?
It usually sits in your site's document root (often public_html or www) on Apache servers. It is a hidden file, so enable "show hidden files" in your file manager or FTP client. If it does not exist, you can create a plain-text file with that exact name.
Should I use Redirect or RewriteRule?
Use the simple Redirect directive (mod_alias) for straightforward one-to-one or folder redirects. Use RewriteRule (mod_rewrite) when you need conditions, such as matching the hostname, HTTPS status or query strings. Avoid mixing both for the same URLs.
Why does my RewriteRule with a leading slash not work in .htaccess?
In .htaccess (per-directory) context, Apache strips the directory prefix before matching, so the pattern never sees a leading slash. Write ^old-page$ rather than ^/old-page$.
Does .htaccess work on Nginx?
No. Nginx does not read .htaccess files. On Nginx, redirects are configured in the server block with return or rewrite directives, usually by your host or developer.
Will a 301 redirect pass rankings to the new URL?
Google treats permanent redirects as a strong signal that the target should be the canonical URL. Redirect to the most relevant equivalent page, not the homepage, to keep the value of the old URL.
Conclusion
Setting up 301 redirects in .htaccess is straightforward once you know the rules: choose the simplest directive that works, always specify 301, drop the leading slash in RewriteRule patterns, place redirects before CMS rules, and test every URL for a single clean hop. Handled carefully, redirects protect rankings through redesigns, HTTPS moves and domain changes.
Planning a migration or untangling years of redirect rules? Read our technical SEO guide for the bigger picture, or get a quote and our team will map, implement and verify every redirect for you.




