.htaccess Redirect Generator

Generate redirect rules for Apache or nginx: single URLs, whole folders, www and HTTPS canonicalisation, and trailing slashes, with the right status code.

Live output

Enable JavaScript to customise; default output below.

Server
Status code

301 is cached hard by browsers. Use 302 while you are still deciding, and 410 for something deliberately deleted.

Live preview redirects.conf
# Redirects. Put this ABOVE the "# BEGIN WordPress" block in .htaccess:
# WordPress's own rules end with [L] and would otherwise run first.
<IfModule mod_rewrite.c>
RewriteEngine On

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

RewriteCond %{REQUEST_URI} ^/old-page/$
RewriteRule ^ /new-page/ [R=301,L]
</IfModule>

Output is valid and updates as you type.

Write redirect rules for Apache or nginx: single pages, whole folders, the www and HTTPS decision, and trailing slashes, each with the status code that means what you intend.

How to use

  1. Use 301 once you are sure. Browsers cache it hard, and a wrong 301 follows visitors around until they clear their cache.
  2. Use 302 while you are still deciding, and 410 for a page you deliberately deleted. 410 tells a crawler to stop asking, which a 404 does not.
  3. Put the rules above the WordPress block in .htaccess. WordPress’s own rules end with [L], so anything after them may never run.
  4. Force one host and one protocol. Serving both www and bare, or both HTTP and HTTPS, is two sites as far as a crawler is concerned.
  5. Behind Cloudflare or any proxy, check X-Forwarded-Proto instead of HTTPS. The connection to the origin is plain HTTP, and checking the wrong thing is an infinite redirect.

Example

A folder move that keeps the rest of the path:

RewriteCond %{REQUEST_URI} ^/old-blog/(.*)$
RewriteRule ^ /articles/%1 [R=301,L]

Matching on REQUEST_URI rather than in the RewriteRule pattern is deliberate: inside .htaccess the rule pattern has the leading slash stripped, which is why ^/old-blog/ never matches there.

Pitfalls

  • A 301 is cached by the browser, often indefinitely. Testing one you are unsure about means clearing your cache, or testing in a private window, every time.
  • Rules placed below the WordPress block may never be reached. The .htaccess rules WordPress writes end with [L].
  • Checking %{HTTPS} behind a proxy gives a redirect loop, because the origin only ever sees HTTP.
  • Chaining redirects costs a round trip each. /a to /b to /c should be /a to /c.
  • A redirect to a page that redirects back is a loop the browser gives up on after about twenty hops, with a blank page.
  • WordPress already canonicalises trailing slashes to match your permalink setting. Adding your own rule on top is where most trailing slash loops come from.
  • RewriteRule patterns are regular expressions. A dot in a path matches any character unless you escape it.
  • Redirecting a whole folder to a single page is a soft 404 in Google’s eyes: better to map the useful URLs and let the rest 410.

Compatibility

mod_rewrite rules work in Apache 2.2 and later, and .htaccess needs AllowOverride FileInfo or more. The [G] flag for 410 has been available since Apache 2.0. nginx has no .htaccess: rules live in the server block and need a reload. 307 preserves the request method, which matters for a POST endpoint that has moved, and is supported by every current browser. The tool runs entirely in your browser.

Frequently asked questions

301 or 302?
301 for a permanent move, once you are certain. 302 while you are testing, because it is not cached the same way.
Where do the rules go in .htaccess?
Above the # BEGIN WordPress block. Below it, WordPress’s rules may match first and stop processing.
Why am I getting a redirect loop?
Usually forcing HTTPS behind a proxy while checking %{HTTPS}, or a trailing slash rule fighting WordPress’s own canonicalisation.
Should I use a plugin instead?
A redirect plugin is easier to manage and logs 404s, at the cost of loading PHP for every hit. Server rules are faster and silent.
What about 410?
Use it for content you removed on purpose. Crawlers drop a 410 faster than a 404, which keeps your index clean.
Weekly drops

New tools, when there are new tools

One email when something worth using ships. No schedule to fill, so no filler.

Your address goes nowhere else, and one click unsubscribes.