// blog/developer/
Back to Blog
Developer · June 1, 2026 · 9 min read · Updated May 22, 2026

How to Write .htaccess Redirects Without Breaking Your Site

How to Write .htaccess Redirects Without Breaking Your Site

If you have ever migrated a website, changed your URL structure, or merged two domains into one, you have probably needed .htaccess redirects. And if you have ever written them by hand, you know the frustration of a single misplaced character sending your entire site into an infinite redirect loop.

The .htaccess file is powerful but unforgiving. It sits in the root of your Apache web server and controls how URLs are processed before your application even sees the request. A correct redirect rule sends visitors and search engines to the right page seamlessly. A broken rule can take your whole site offline.

The good news is that most redirect scenarios follow predictable patterns. Once you understand the basics of RewriteRule syntax and the difference between a 301 and a 302, you can handle 90% of redirect needs without touching a regex reference guide.

* * *

301 vs 302: Choosing the Right Redirect Type

This is the first decision you need to make, and getting it wrong has real SEO consequences.

A 301 redirect tells browsers and search engines that the page has permanently moved to a new URL. Search engines will transfer the old page's ranking signals to the new URL. This is what you want for site migrations, domain changes, and permanent URL restructuring.

A 302 redirect signals a temporary move. The old URL keeps its search engine rankings because Google expects the content to return there eventually. Use this for A/B testing, seasonal campaigns, or when you are temporarily showing content from a different URL.

The syntax difference in .htaccess is minimal:

`apache # 301 Permanent redirect Redirect 301 /old-page.html /new-page.html

# 302 Temporary redirect Redirect 302 /sale /summer-sale-2026 `

A common mistake is using 302 redirects for permanent changes. Your site works fine for visitors, but search engines keep indexing the old URL and never pass ranking value to the new one. If you changed the URL permanently, always use 301.

Terminal window showing Apache server configuration
Terminal window showing Apache server configuration
* * *

Simple Redirects vs RewriteRule

Apache gives you two ways to handle redirects in .htaccess, and they serve different purposes.

The Redirect directive is the simpler option. It maps one URL path to another with minimal syntax:

`apache Redirect 301 /blog/old-post /blog/new-post Redirect 301 /about-us /about `

This works perfectly for one-to-one URL mappings. No regex, no conditions, just straightforward path replacement.

RewriteRule is more powerful and handles patterns, conditions, and complex logic:

`apache RewriteEngine On RewriteRule ^blog/category/(.*)$ /blog/topics/$1 [R=301,L] `

This redirects any URL under /blog/category/ to the same path under /blog/topics/. The (.*) captures everything after the prefix, and $1 inserts it into the destination.

Use Redirect when you have a fixed list of old-to-new URL pairs. Use RewriteRule when you need patterns, conditions (like checking HTTP vs HTTPS), or query string manipulation.

Before writing redirect rules, make sure your URLs are properly formatted. The Slug Generator creates clean, URL-safe slugs from page titles, which helps you plan your new URL structure before setting up redirects.

Key takeaway

Apache gives you two ways to handle redirects in .htaccess, and they serve different purposes.

* * *

Common Redirect Patterns You Will Actually Use

Here are the redirect scenarios that come up again and again in real projects:

Redirect HTTP to HTTPS: `apache RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L] `

Redirect www to non-www (or vice versa): `apache RewriteEngine On RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC] RewriteRule ^(.*)$ https://example.com/$1 [R=301,L] `

Redirect an entire directory: `apache RewriteEngine On RewriteRule ^old-section/(.*)$ /new-section/$1 [R=301,L] `

Remove trailing slashes: `apache RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)/$ /$1 [R=301,L] `

Add trailing slashes: `apache RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*[^/])$ /$1/ [R=301,L] `

Pick one trailing slash convention and stick with it across your entire site. Mixing both creates duplicate content issues that confuse search engines.

* * *

Regex Basics for .htaccess (Just Enough to Be Dangerous)

You do not need to be a regex expert to write .htaccess rules. These six patterns cover the vast majority of redirect scenarios:

  • ^ matches the start of the URL path
  • $ matches the end of the URL path
  • (.*) captures any sequence of characters (greedy)
  • ([^/]+) captures one URL segment (everything except a slash)
  • [NC] makes the match case-insensitive
  • [R=301,L] sets the redirect type and marks this as the Last rule to process

A practical example combining these:

`apache RewriteRule ^products/([^/]+)/([^/]+)$ /shop/$1/$2 [R=301,L] `

This redirects /products/shoes/nike-air to /shop/shoes/nike-air. The two ([^/]+) groups capture the category and product slug separately.

When your redirect rules involve encoded characters in URLs, use the URL Encoder to verify that special characters are properly encoded. A space in a URL should be %20, and ampersands need to be %26 in query strings. Getting encoding wrong is a common source of redirect failures.

Developer working on website migration with multiple browser tabs
Developer working on website migration with multiple browser tabs
* * *

Testing and Debugging .htaccess Rules

The single most important rule of .htaccess editing: always test before deploying to production.

Test locally first. If you run a local Apache server (XAMPP, MAMP, or native Apache), test your rules there. An infinite redirect loop on localhost just crashes a browser tab. On production, it can take your site down for all visitors.

Check for redirect chains. A redirect chain happens when URL A redirects to URL B, which redirects to URL C. Each hop adds latency and dilutes SEO value. Use browser developer tools (Network tab) to verify that your redirects resolve in a single hop.

Watch for infinite loops. The classic loop happens when Rule A redirects /old to /new, and Rule B redirects /new back to /old. Or when a rule matches its own output. Always add the [L] flag to stop processing after a match.

Test with curl: `bash curl -I -L https://example.com/old-url `

The -I flag shows headers only, and -L follows redirects. You will see the full redirect chain with HTTP status codes for each hop.

Check the error log. Apache logs rewrite errors to its error log. If your rules are not working and you cannot figure out why, the error log usually contains the answer. Enable RewriteLog temporarily for detailed rule-by-rule trace output.

Before deploying, test your regex patterns separately. The Regex Tester lets you verify that capture groups and character classes match the URLs you expect, before they go live in .htaccess.

* * *

Mistakes That Will Ruin Your Day

Experienced developers still make these mistakes because .htaccess is surprisingly easy to break:

Forgetting RewriteEngine On. Every file that uses RewriteRule needs this line at the top. Without it, all your rewrite rules are silently ignored. No error, no warning, just nothing happens.

Not escaping dots in regex. In regex, a dot matches any character. If you write RewriteRule ^example.com/(.*)$, the dot in example.com matches exampleXcom too. Escape it: example\.com.

Ordering rules wrong. Apache processes rules top to bottom. If a general rule appears before a specific one, the general rule catches the request first. Put specific rules above general ones.

Missing the leading slash context. In .htaccess files, the URL path passed to RewriteRule does NOT include a leading slash. So ^/about$ will never match. Use ^about$ instead.

Not backing up. Before editing .htaccess on a live server, copy the current file. If something breaks, you can restore the backup in seconds. A broken .htaccess can return 500 errors on every page of your site.

Key takeaway

Experienced developers still make these mistakes because .htaccess is surprisingly easy to break: **Forgetting RewriteEngine On.** Every file that uses RewriteRule needs this line at the top.

* * *

FAQ

Does .htaccess work on Nginx servers?

No. The .htaccess file is an Apache-specific feature. Nginx uses a completely different configuration format in its server block files. If your site runs on Nginx, you need to convert your redirect rules to Nginx syntax. The concepts (301 vs 302, regex patterns) are the same, but the file format is different.

How many redirects can I put in one .htaccess file?

There is no hard limit, but performance degrades with very large files. Each request processes every rule sequentially until a match is found. For sites with hundreds of redirects, consider using a redirect map (RewriteMap) instead of individual rules. This loads all mappings into memory once rather than processing them line by line.

Will removing old redirect rules break anything?

Potentially, yes. If external sites link to your old URL and the redirect is the only thing sending visitors to the right page, removing the rule means those links become 404 errors. Keep redirects in place for at least a year after a URL change, or permanently if the old URLs are linked from sources you do not control.

Can I redirect based on query parameters?

Yes, but not with the Redirect directive. You need RewriteCond to match query strings: `apache RewriteCond %{QUERY_STRING} ^id=42$ RewriteRule ^product\.php$ /products/widget [R=301,L] ` This redirects /product.php?id=42 to /products/widget.