← Back to blog

Apache 301 Redirect: Copy-Paste Rules That Actually Work

August 23, 2026
Apache 301 Redirect: Copy-Paste Rules That Actually Work

Use a one-line Redirect 301 for simple moves; reach for mod_rewrite only when you need to inspect the host, query string, or another request attribute. The simplest working example looks like this:

Redirect 301 /old-page https://example.com/new-page

Drop that into .htaccess and it works on the next request, no server restart needed, as long as AllowOverride permits it in that directory. If you're just mapping one URL to another, stop there. If you need pattern matching, conditions, or logic based on the visitor's request, that's when mod_rewrite earns its complexity.

  • Simple one-to-one move: Redirect 301
  • Pattern, condition, or query-string logic: RewriteRule with RewriteCond
  • Testing a rule you're not sure about: use 302 until it's confirmed correct

Key Takeaways

A correct Apache 301 redirect starts with choosing mod_alias for simple moves and mod_rewrite only for conditional logic, then verifying with 302 before committing to 301.

PointDetails
Match the tool to the taskUse Redirect 301 for static moves; reserve mod_rewrite for host, query-string, or pattern-based logic.
Test before you commitDeploy with 302 first since browsers and search engines can cache a 301 for weeks.
Watch context-specific syntaxDrop the leading slash in .htaccess patterns; VirtualHost keeps it.
Avoid chains and loopsPoint directly to the final URL, and constrain regex so the [L] flag can't cause a re-match loop.
Verify with the right toolsPingfloat's Redirect Rule Generator and Response Headers Inspector confirm rules work before you ship them.

Table of Contents

How Do You Choose Between Apache Redirect Methods?

Apache gives you two separate modules for redirects, and picking the wrong one is the most common source of confusion in htaccess redirect rules. mod_alias handles the Redirect and RedirectMatch directives. mod_rewrite handles RewriteRule and RewriteCond. They solve overlapping problems but were built for different jobs.

Technician's hand adjusting cables on server rack

mod_alias is the right call for anything static: a page that moved, a folder that got renamed, a whole domain that needs to point somewhere else while keeping the same path structure. It's lightweight, preserves the request path by default, and does exactly what it says with no surprises. Apache's own documentation is blunt about this: reach for mod_alias before mod_rewrite whenever the redirect is simple, because mod_rewrite carries more processing overhead and more ways to misconfigure it.

mod_rewrite earns its keep when you need to check something beyond the URL path itself. Inspecting the Host header to force a canonical domain, reading a query string, checking a cookie, or matching a complex regex pattern across many URLs at once. That's mod_rewrite territory.

The order-of-execution detail catches people off guard: in server or virtual host context, mod_rewrite rules process before mod_alias. Inside a .htaccess file, that ordering flips, and mod_alias runs first. Mix both modules in the same scope and you can get redirect behavior that contradicts what the file order suggests.

  • Static, one-to-one, or prefix redirects: use mod_alias
  • Conditional logic, host checks, or query-string manipulation: use mod_rewrite
  • Never assume both modules will process rules in the order you wrote them

Pro Tip: Pick one module per file. If a .htaccess file mixes Redirect and RewriteRule directives, debugging becomes a guessing game about which rule fired first. Keep redirect logic in one module and you'll spend far less time troubleshooting.

What Are the Most Common Apache Redirect Examples?

Most real-world redirect needs fall into five patterns. Here's each one, ready to adapt.

  1. Single page. Redirect 301 /old-page https://example.com/new-page moves one URL to another, keeping full control over the destination.
  2. Folder or subtree. RedirectMatch 301 ^/blog/(.*)$ https://example.com/articles/$1 catches everything under /blog/ and remaps it, preserving whatever came after the folder name. Anchor the pattern with ^ and $ or you'll accidentally match partial strings elsewhere on the site.
  3. Domain migration preserving path. RewriteRule ^(.*)$ https://newdomain.com$1 [R=301,L] sends every request on the old domain to the same path on the new one, which is the version InMotion Hosting's deployment guide recommends for full-site moves.
  4. Force www or non-www, and force HTTPS. For redirecting www to non-www in htaccess:
    RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
    RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
    
    Flip the condition to redirect non-www to www instead. For HTTP to HTTPS in Apache:
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{http_host}%{request_uri} [R=301,L]
    
  5. Trailing slash. Apply a trailing-slash rule only when your app treats /page and /page/ as different resources; otherwise you risk creating a redirect for URLs that already work fine.

Every one of these can run in a virtual host or in .htaccess — placement changes how you write the pattern, which the next section covers.

Where Should Redirect Rules Actually Live?

Server-config and virtual host redirects run once, at server startup, and apply to every request without Apache re-reading a file each time. That's why Apache's own remapping documentation recommends VirtualHost placement for production sites whenever you have access to the server config. A domain-wide HTTPS redirect there looks like this:

<VirtualHost *:80>
    ServerName example.com
    Redirect 301 / https://example.com/
</VirtualHost>

.htaccess remains the practical choice on shared hosting where you can't touch the main config. The catch that trips up almost everyone moving from VirtualHost to .htaccess: per-directory context strips the directory prefix before matching. A pattern written as ^/old-page in a VirtualHost block needs to become ^old-page (no leading slash) inside .htaccess, because Apache has already removed the directory portion by the time the rule evaluates.

Before assuming a rule is broken, confirm the basics:

  • Check that AllowOverride All (or at least AllowOverride FileInfo) is set for that directory, otherwise .htaccess rules get silently ignored.
  • Confirm mod_rewrite or mod_alias is actually loaded (apachectl -M on most Linux distributions).
  • Verify the .htaccess file sits in the directory it's supposed to govern, not one level up or down.

Pro Tip: Run curl -I https://example.com/old-page before and after deploying a rule. It shows the raw status code and Location header without any browser cache getting in the way, which is the fastest way to confirm a rule actually fired.

Why Isn't My Apache Redirect Working?

Browsers cache 301 responses aggressively, sometimes for weeks, which means a broken rule can look "fixed" in your browser while still misbehaving for everyone else. Apache's per-directory documentation is explicit about this: test with a 302 first, confirm the destination is correct, and only switch to 301 once you're sure. Search engines cache 301s too, so an incorrect permanent redirect can linger in an index for a long stretch.

Four failure patterns account for most support tickets:

  • Redirect chains. Old URL points to a second old URL, which finally points to the real destination. Each hop adds latency and dilutes the signal you're trying to preserve. Point directly at the final destination instead.
  • AllowOverride blocking everything. If it's set to None, your .htaccess rules simply never run, and Apache won't necessarily tell you why.
  • Module not loaded. A rule referencing RewriteEngine On does nothing if mod_rewrite isn't enabled on that server.
  • Rule order and mixing. As covered earlier, mod_alias and mod_rewrite process in different orders depending on context, and two rules stacked in the wrong sequence can override each other silently.

Query strings add another wrinkle. Redirect and RedirectMatch carry the original query string along automatically, while RewriteRule does the same by default unless you add flags to change that behavior, covered next.

What Do the QSA and QSD Flags Actually Do?

Inside .htaccess, dropping the leading ^/ from a pattern is non-negotiable, because per-directory context has already stripped it. A rule written as RewriteRule ^/products/(.*)$ ... will simply never match inside .htaccess; it needs to read RewriteRule ^products/(.*)$ ... instead.

The [L] flag stops the current rewrite pass, but it doesn't guarantee the engine won't run again. If your substituted URL still matches the same pattern, Apache can re-enter the rule on the next pass and create a loop. Constrain your regex or add a RewriteCond that excludes the already-rewritten form.

On query strings: RewriteRule passes the original query string through by default. Add QSA to append new parameters onto the existing ones, or QSD to drop the query string entirely, both documented in Apache's mod_rewrite guide.

  • Never accept a full URL from user input as a redirect target; validate against an allowlist or restrict to relative paths, or you've built an open-redirect vulnerability.
  • Test any rule touching query strings with a URL that actually has parameters attached, not just the bare path.

Pro Tip: If a rewrite rule seems to randomly stop working after a few requests, suspect a loop or a caching layer, not a syntax error, since syntax errors that will actually throw a 500 tend to fail loudly, not intermittently.

What Should Every Developer Remember About Apache Redirects?

Three rules cover nearly every situation you'll run into: pick the simplest directive that solves the problem, always test with a 302 before switching to 301, and never let a redirect chain more than one hop from old URL to new. Most of the debugging pain in Apache redirect work traces back to skipping one of those three.

Beyond the rules, tooling matters. Pingfloat's Redirect Rule Generator builds correct .htaccess or VirtualHost snippets without you having to remember whether a leading slash belongs in the pattern. Pair that with a quick HTTP status code check while testing, since confirming you're actually looking at a 301 and not a cached 200 saves real debugging time.

Build and Verify Redirects Without Guesswork

Writing redirect syntax by hand is where most mistakes creep in: a missing slash, a forgotten L] flag, a RewriteCond that doesn't quite match the intended host. Pingfloat's [Redirect Rule Generator builds correct .htaccess or VirtualHost snippets for single-page moves, domain migrations, and www or HTTPS canonicalization, so you're pasting tested syntax instead of debugging your own typos.

Pingfloat

Once a rule is live, verify it the right way. Pingfloat's HTTP Status Codes Reference confirms what each response code actually means, and the Response Headers Inspector shows the exact Location header and cache directives your server is returning, catching cases where a browser's cached 301 is hiding a rule that's actually broken. Run your test in an incognito window, confirm the status with curl -I, then check the headers directly through Pingfloat before you consider the redirect finished.

Where to Read the Official Apache Documentation

Frequently Asked Questions

What's the difference between a 301 and a 302 redirect in Apache? A 301 tells browsers and search engines the move is permanent, and they'll cache that response, sometimes for weeks. A 302 signals a temporary move and isn't cached the same way, which is exactly why it's the safer choice while you're still confirming a rule works.

Does .htaccess require a server restart to apply redirect rules? No. Apache reads .htaccess on every request, so a saved change takes effect on the next page load, as long as AllowOverride permits it for that directory.

Why does my RewriteRule work in VirtualHost but not in .htaccess? Per-directory context strips the directory prefix before matching, so a pattern written with a leading slash in VirtualHost config needs that slash removed inside .htaccess.

Can I redirect www to non-www and enforce HTTPS in the same file? Yes. Stack both RewriteCond blocks in the same .htaccess or VirtualHost file, one checking HTTP_HOST for the www prefix and another checking HTTPS status, each followed by its own RewriteRule.

Frequently Asked Questions — overview diagram

Will a 301 redirect hurt my search rankings? A properly configured single-hop 301 generally preserves the ranking signal associated with the old URL. What actually causes damage is redirect chains, since each extra hop adds latency and increases the chance a crawler gives up before reaching the final destination.

Sources