My Tool Studio
SEO Tools·5 min read

How Htaccess Redirects Work: Apache 301s Explained

Knowing how htaccess redirects work is the difference between a clean site migration and a weekend of 500 errors. The .htaccess file is Apache's per-directory config: the server reads it on every request, top to bottom, and the matching rules decide where each visitor ends up. That makes it flexible and unforgiving in equal measure, since a single stray character applies to every URL you serve. This guide walks through the rules the Htaccess Redirect Generator writes, a worked rule read token by token, the 301 versus 302 decision, and how to test before anything reaches production.

Htaccess Redirect Generatormytoolstudio.com › tools<title>…</title><meta name="description">SEO ready

The migration weekend where the .htaccess file earns its keep

One file, every old URL.

Picture a company moving from shop.example-store.com to example-store.com/shop after a rebrand. Hundreds of product URLs have backlinks, bookmarks and rankings attached. If those old addresses start returning 404s on Monday, years of accumulated authority disappear and revenue follows it down. The fix lives in one Apache config file: a set of 301 rules that catch each old path and forward it, permanently, to its new home.

The same file handles the quieter moves too: switching to HTTPS, settling the www question and removing trailing slash duplicates. On Apache, and on LiteSpeed, which reads the same rules, they all belong in .htaccess.

How htaccess redirects work inside Apache

Two modules, and why the generator uses one.

Apache offers two ways to redirect. The simple one is mod_alias: a line like Redirect 301 /old-page /new-page matches a path prefix and sends the browser elsewhere, with no conditions and no patterns. The heavier one is mod_rewrite. A RewriteRule applies a regular expression to the requested path, and RewriteCond lines above it add conditions on things like the hostname, the query string or whether HTTPS is on.

The generator writes everything with mod_rewrite, inside an IfModule mod_rewrite.c block. Mixing the two styles makes the order of rules hard to predict, because the modules run separately. The IfModule wrapper is a safety guard: if mod_rewrite isn't enabled, Apache skips the block instead of returning a 500 error on every request.

Order matters inside the block. Rules run top to bottom, and the L flag stops processing once a rule fires. The generator puts page redirects first and points each one at a full https address, so an old URL goes straight to its final home in one hop instead of passing through the HTTPS and www rules on the way.

A worked htaccess rule, read token by token

The HTTPS and www rule, decoded.

With Force HTTPS and Remove www ticked, which is the default, the generator writes one combined rule. Line one: RewriteCond %{HTTPS} off [OR]. Line two: RewriteCond %{HTTP_HOST} ^www\. [NC]. Line three: RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]. Line four: RewriteRule ^ https://%1%{REQUEST_URI} [L,R=301].

The first two conditions are joined by OR, so the rule fires when the request arrived over plain HTTP or when the host starts with www. The third condition always matches, but it captures the host without its www prefix into %1. The rule uses ^ as its pattern, which matches every path, because the conditions already did the filtering. The target rebuilds the address from https://, the bare host and %{REQUEST_URI}, the requested path. Apache carries the query string over on its own. R=301 makes the redirect permanent and L stops later rules from touching the request.

So a request for http://www.example.com/pricing?plan=pro answers with one 301 and a Location header of https://example.com/pricing?plan=pro. Separate HTTPS and www rules would take two hops to get there. Add a page redirect line such as /old-pricing /pricing and the generator writes RewriteRule ^old-pricing/?$ https://example.com/pricing [R=301,L] above it, so that legacy path lands on the final address directly.

301 vs 302 in .htaccess: one number, two promises

Permanent or temporary, choose deliberately.

The difference is a single digit in the flag, but the consequences last for months. R=301 tells browsers and crawlers the move is permanent: caches store it, Google treats the target as the page to index and passes signals to it, and the old URL drops out over time. R=302 says the move is temporary, so search engines may keep the original URL indexed and wait for it to come back.

Use 301 for migrations, rebrands and merged pages, and keep 302 for short-lived situations, such as a seasonal page that will return. In the generator, the Redirect type setting applies to every rule, and you can override it for one page redirect by adding 301 or 302 at the end of its line. The expensive mistake is shipping 302s during a migration because a plugin defaulted to them; signals stall on old URLs while the new ones start from nothing.

Turning a migration sheet into rules

Two columns in, one rule per line out.

Most migrations start as a spreadsheet with an old URL column and a new URL column. Copy both columns into the Page redirects box and each line becomes an exact-match rule. Tabs, commas or spaces all work as separators, and full old URLs are reduced to their path. A header row such as Old URL, New URL, or any line that doesn't look like two URLs, is listed as skipped rather than written as a broken rule.

Old URLs with a query string get special handling. Paste https://example.com/shop?id=12 with its new address and the generator adds a RewriteCond that matches that exact query string, plus the QSD flag so the old query isn't carried onto the new URL. QSD needs Apache 2.4 or newer.

Htaccess mistakes that take whole sites down

Learned the hard way, repeatedly.

Because Apache reads .htaccess on every request, errors hit instantly and everywhere. These are the classics:

  • A syntax typo, even one misspelled directive, returns 500 for the entire site, not just the broken rule.
  • Redirect loops behind a proxy or CDN, such as Cloudflare in Flexible SSL mode, where the HTTPS check always sees off and redirects forever.
  • Pasting new rules below a WordPress or other CMS block that already rewrites every request, so your rules never run.
  • Writing a target with its own ? by hand, which replaces the visitor's query string unless you add the QSA flag, silently stripping tracking parameters.
  • Sending every old page to the home page, which Google tends to treat like a missing page rather than a move.

Testing rewrite rules before they touch production

Three habits, zero downtime.

Never compose rules on the live server. Build the file in the Htaccess Redirect Generator, then stage it: a subdomain, a local Apache in Docker, or your host's staging copy all work. Curl is a good verifier; curl -I http://example.com/old-page shows the status line and Location header without a browser cache muddying the result.

Change one thing at a time, because two new rules that interact are much harder to debug than one. And keep the previous file as .htaccess.bak beside the new one, so rollback is a rename.

Where the Htaccess Redirect Generator hands off to other tools

Generate here, verify elsewhere.

The Htaccess Redirect Generator writes the rules; proving they behave is a separate job. After deploying, run key old URLs through the Redirect Checker to confirm each one reaches its destination in a single hop. To check a whole migration sheet at once, paste old and new URL pairs into the Redirect Checker's Bulk tab, which marks every row that lands on the wrong target, or paste up to 100 URLs into the HTTP Status Code Checker and export the results.

If your duplicate problem is about which version of a live page should rank, rather than forwarding dead ones, that's a job for the Canonical Tag Generator instead. A canonical keeps both URLs reachable while a redirect removes one from circulation.

Try it now

Open Htaccess Redirect Generator

The tool is one click away. No sign up, no upload, no payment.

Open Htaccess Redirect Generator