apache

.htaccess Redirect Cookbook: Every RewriteRule You Actually Need

RC
Redirect Check Team
10 min read

If you're on Apache, .htaccess is where redirects live. This cookbook covers every pattern you'll actually need — no filler, just the rules, what they do, and the gotchas.

Your three tools

  • Redirect (mod_alias) — simple path-to-path redirects, no regex.
  • RedirectMatch (mod_alias) — path-to-path with regex.
  • RewriteRule (mod_rewrite) — everything else, including conditional logic.

Rule of thumb: use Redirect for simple cases, RewriteRule for anything touching query strings, hosts, or conditions.

Simple redirects with Redirect

# Permanent redirect for a single page
Redirect 301 /old-page.html /new-page.html

# Permanent redirect for an entire directory
Redirect 301 /old-docs /docs

# Temporary (302)
Redirect 302 /sale /promo

# Gone (410)
Redirect gone /discontinued.html

The Redirect directive does a prefix match. Redirect 301 /old-docs /docs will redirect /old-docs/foo to /docs/foo automatically.

Pattern matching with RedirectMatch

# Redirect all .html to clean URLs
RedirectMatch 301 ^/(.*)\.html$ /$1

# Redirect numbered blog posts to slug-based URLs
RedirectMatch 301 ^/post/(\d+)$ /blog/archive/$1

RewriteRule: the heavy lifter

Any time you need to inspect the host, query string, headers, or environment, use RewriteRule with RewriteCond.

RewriteEngine On

# Force HTTPS
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

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

# Redirect non-www to www (pick one and stick with it)
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [R=301,L]

Flags you need to know

  • R=301 — send a 301 response (use R=302 for temporary)
  • L — last rule; stop processing further rewrites
  • NC — case-insensitive match
  • QSA — append original query string
  • QSD — discard original query string

Common cookbook entries

HTTP to HTTPS

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Behind a load balancer or Cloudflare Flexible SSL, %{HTTPS} is always off. Use:

RewriteCond %{HTTP:X-Forwarded-Proto} !=https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Remove trailing slash

RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ /$1 [R=301,L]

Redirect based on query string

# /search?q=foo -> /search/foo
RewriteCond %{QUERY_STRING} ^q=([^&]+)$
RewriteRule ^search$ /search/%1? [R=301,L]

The trailing ? in the target removes the original query string.

Redirect by user agent

RewriteCond %{HTTP_USER_AGENT} (iPhone|Android) [NC]
RewriteRule ^/?$ /mobile [R=302,L]

Bulk redirects from a mapping file

# In httpd.conf (not .htaccess):
RewriteMap redirects txt:/etc/apache2/redirects.txt

# Then in .htaccess:
RewriteCond ${redirects:$1} !=""
RewriteRule ^(.*)$ ${redirects:$1} [R=301,L]

Gotchas

  • Order matters. Rules are evaluated top-down. Put the most specific rules first, and use the L flag to stop processing.
  • Rewrite loops. If your rule matches its own output, you'll get an infinite loop and an HTTP 500. Use RewriteCond to exclude the target.
  • .htaccess is slow. Apache re-reads it on every request. For high-traffic sites, put rules in the main config.
  • Backticks and dollar signs. In regex, $1 is a back-reference; in RewriteCond patterns, %1 refers to the condition's capture groups.
  • Escaping dots. Always write example\.com, not example.com, in regex patterns — unescaped dots match any character.

Debugging a .htaccess that's misbehaving

  1. Add LogLevel alert rewrite:trace6 to your vhost config (not .htaccess) to dump rewrite traces to the error log.
  2. tail -f /var/log/apache2/error.log and make a request.
  3. Test with curl -I -L to follow the whole chain.
  4. Remember to turn the trace logging back off in production — it's verbose.

Wrap-up

For anything more complex than a single page redirect, reach for RewriteRule. Keep rules ordered from specific to general, always set R=301 or R=302 explicitly, and test the full chain before deploying. After any change, verify with Redirect Check to make sure you haven't introduced a loop or a stray 302 where you meant 301.

지금 리디렉션을 검사하세요

잘못된 리디렉션이 SEO에 피해를 주지 않도록 하세요. 무료 도구로 링크를 즉시 감사하세요.

#apache#htaccess#tutorial
이 글 공유하기: