Paste a list of old and new paths and get redirect rules for Apache, nginx, Netlify, Vercel or Cloudflare. Capture groups carry over, and the input panel warns about duplicates, chains and a path that redirects to itself.
Use 301 only when the move is final. It passes ranking to the new URL, and browsers cache it hard, sometimes for months. You cannot clear a visitor's cache remotely.
The original URL stays canonical. Use it for maintenance pages, A/B tests and anything you intend to undo.
The strict versions. Clients following a 301 or 302 have historically turned a POST into a GET; 308 and 307 forbid that. Use them when a form submission has to survive the redirect.
Each hop in a chain costs a round trip, and search engines stop following after a few. Point every old URL straight at its final destination.
Order your rules from specific to broad. In Apache and nginx the first matching rule wins, so a broad pattern above a specific one catches its traffic without any error. This is why a rule that works alone can stop working after you add ten more above it.
The other common failure is a loop: the destination matches the
source pattern, so it redirects to itself until the browser gives
up. Anchor patterns with ^ and $ instead
of matching anywhere in the path. The generator flags a line whose
source and destination are identical, but it cannot tell whether a
regex target re-matches its own pattern.
This page generates rules and cannot check a live URL, and no browser-based tool can. The fetch API hides the status code and the Location header of a cross-origin redirect and returns an opaque response with a status of 0, while CORS blocks following it. Checking a real URL requires a server or a terminal.
curl -sIL https://example.com/old-path prints every
hop with its status code. We recommend running it on staging
before you ship a few hundred 301s.
# Simple moves: Redirect is cheaper than RewriteRule
Redirect 301 /about-us /about
# Patterns need mod_rewrite
RewriteEngine On
RewriteRule ^docs/v1/(.*)$ /docs/v2/$1 [R=301,L]
# Force https, once, at the top
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
# Order matters: the first match wins, so specific rules
# go above general ones or they never fire. server {
# Exact matches are the fastest lookup nginx has
location = /about-us { return 301 /about; }
# Patterns
rewrite ^/docs/v1/(.*)$ /docs/v2/$1 permanent;
# permanent = 301, redirect = 302
# For 307/308 use return with the code explicitly:
location = /form { return 308 /new-form; }
}
# A whole-host move, without a rewrite
server {
server_name old.example.com;
return 301 https://new.example.com$request_uri;
} # Every hop with its status code
curl -sIL https://example.com/old-path | grep -E "^(HTTP|location)"
# Check a whole list before and after deploying
while IFS=, read -r from to; do
code=$(curl -s -o /dev/null -w "%{http_code}" "https://example.com$from")
echo "$code $from -> $to"
done < redirects.csv
# This cannot be done from a browser: the fetch API hides the
# status and Location of a cross-origin redirect on purpose. Run this against staging before shipping a batch. A wrongly issued 301 is cached on visitors' machines and cannot be recalled.
Every old URL should reach its final home in one hop. Each hop in a chain costs a round trip, and search engines stop following after a handful, so ranking signals are lost. On a second site migration, rewrite the first set of rules to point at the final destination instead of layering new ones on top.
This tool follows the specifications below. Read them when you need the exact normative wording, for example to settle an edge case between two implementations.
Apache .htaccess (Redirect or RewriteRule), nginx, Netlify _redirects, Vercel vercel.json and Cloudflare _redirects. Paste the pairs once and switch Format to whichever your host reads.
Use 301 when the move is permanent: it passes ranking signals, and browsers cache it, sometimes for months. Use 302 when it is temporary. If you are unsure, start with 302, because a wrongly issued 301 stays cached on visitors' machines and you cannot clear it remotely.
They are the strict versions. Clients following a 301 or 302 have historically turned a POST into a GET; 308 and 307 forbid that. For plain page moves, 301 and 302 are fine and better understood by older tooling.
Yes, in both Apache and nginx. The first matching rule wins, so a broad pattern above a specific one catches its traffic. Put your exact-match redirects first and the wildcards last.
The destination matches the source pattern, so it redirects to itself forever. Check that the target is excluded from the rule, which usually means anchoring the pattern with ^ and $ rather than matching anywhere in the path.
No, and no browser-based tool can. The fetch API hides the status code and Location header of a cross-origin redirect and returns an opaque response, so following a redirect chain requires a server. Verify the rules with curl -sIL or your host's own tooling.
The HTTP status reference covers each code in more detail. The slug generator builds the new paths, and the URL parser breaks apart the old ones.