Redirect Rule Generator for Apache and Nginx
Paste your old and new URLs. Get rules that work, and a warning about the chains hiding in them. Nothing you paste leaves your browser.
Getting redirects right
Redirects are the plumbing of a site migration, and a surprising amount of lost search traffic traces back to a move where they were done carelessly. The rules are not complicated, but three details decide whether the output works, and generated rule sets get all three wrong regularly.
1. The leading slash, in Apache
This is the one that costs people afternoons. In a per-directory context — which is what a .htaccess file is — Apache strips the leading slash from the URL path before matching it against your pattern. So this never matches anything:
RewriteRule ^/old-page$ /new-page [R=301,L]
And this does:
RewriteRule ^old-page$ /new-page [R=301,L]
There is no error. The file loads, the rule sits there, and nothing happens. This tool always emits the pattern without the leading slash, because that is the only form that works where people actually put these rules.
2. Query strings need a different mechanism
Redirect and RewriteRule both match against the path only. Neither can see the query string, so a rule for /product?id=5 will never fire however carefully you write it.
Matching a query string means a RewriteCond:
RewriteCond %{QUERY_STRING} ^id=5$
RewriteRule ^product$ /products/widget? [R=301,L]
The trailing ? on the destination matters. Without it Apache appends the original query string to the new URL, and you land on /products/widget?id=5. The tool adds it for you and switches to this form automatically whenever a source URL contains a query.
3. Chains, and why they accumulate
A chain is a redirect pointing at another redirect:
/old-page -> /newer-page -> /newest-page
Every hop is a separate request. Visitors wait longer, and each hop spends a slice of crawl budget delivering nothing. Google follows a limited number before giving up entirely.
Chains are rarely deliberate. A site moves to https, then restructures its URLs, then retires a category, and each change adds a layer to rules written months apart by different people. Nobody sets out to build a five-hop chain; it assembles itself.
The fix is to flatten: point every old URL straight at the final destination in one hop and delete the intermediate rules. This tool traces every chain in your list and shows you the full path, so you can collapse them before they ship rather than finding them in a crawl report later.
It also flags loops, where A points to B and B points back to A. Those do not merely waste requests; the page becomes unreachable for everyone. And duplicate sources, where the same old URL appears twice with different destinations — Apache uses the first and silently ignores the rest.
Choosing the status code
Use 301 unless the old URL is genuinely coming back. The old advice that 301 passes ranking value and 302 does not is out of date; Google passes signals through both. What differs is which URL survives in the index. A 301 retires the old address. A 302 keeps it, because you said the move was temporary — so a permanent move marked 302 leaves the old URL ranking and the new one struggling.
307 and 308 preserve the HTTP method across the redirect. That matters for APIs and form posts, and almost never for ordinary page moves.
Redirect to the closest equivalent, or do not redirect
When a page goes away, send it to whatever most nearly replaces it. Mass-redirecting removed pages to the home page is the classic migration shortcut, and Google treats those as soft 404s: it can tell the destination has nothing to do with the request, declines to pass the signal, and often drops the URL anyway. You pay the cost and get none of the benefit, plus visitors arriving somewhere baffling.
If nothing equivalent exists, do not invent a destination. Return 410 Gone and let the URL drop cleanly. That is the honest answer and Google handles it well. See HTTP status codes.
A migration order that works
- Export every indexed URL first. Search Console, your sitemap, analytics, and a full crawl. You cannot map what you have not listed.
- Map old to new, one by one, in a spreadsheet. Every old URL gets a destination or an explicit decision to let it 410.
- Generate the rules here and check the chain report before deploying.
- Update your internal links to point at the new URLs. Do not rely on redirects for your own navigation; an internal link to a redirect is a weakened signal.
- Update canonicals and the sitemap. An old sitemap full of redirecting URLs undoes a lot of careful work.
- Keep the redirects at least a year. Google needs repeated crawls to move the signals, and old inbound links live a long time.
What this tool cannot do
It cannot check whether your destinations return 200, because that would mean fetching them, and nothing you paste here leaves your browser. After deploying, verify with one command per URL:
curl -sIL https://example.com/old-page | grep -i "^HTTP\|^location"
You want exactly one 301 followed by one 200. More than two status lines means a chain survived. Redirects for SEO covers the whole subject in more depth.
One last thing: keep a copy of your .htaccess before editing it. A malformed rewrite rule returns a 500 on every page of the site, and the quickest fix is always putting the old file back.
Frequently asked questions
Should I use 301 or 302?
A 301 unless the old URL is genuinely coming back. The practical difference is which URL Google keeps: with a 301 it drops the old address and indexes the new one, with a 302 it keeps the old one because you said the move was temporary. Using 302 for a permanent move is why an old URL sometimes refuses to disappear from search.
Why does the RewriteRule have no leading slash?
Because in a per-directory .htaccess file, Apache strips the leading slash before matching. A pattern written as ^/old-page$ will never match anything. This catches out a great many generated rule sets, and it is silent: the file loads, the rules simply do nothing.
What is a redirect chain and why does it matter?
It is a redirect pointing at another redirect. Each hop is a separate request, so visitors wait longer and crawlers spend budget delivering nothing. Google follows only a limited number of hops before giving up. Chains build up naturally after a couple of site changes, which is why this tool looks for them.
Can it check whether my new URLs actually work?
No. That would need the tool to fetch each destination, which means sending your URLs to a server, and everything here runs in your browser. Test the destinations yourself with curl -I, or a crawler, after you deploy.
Where do these rules go?
The Apache rules go in the .htaccess file in your site root, or in the virtual host config. The Nginx rules go in your server block, and the map form goes in the http block. Always keep a copy of the original file before editing: a bad rewrite rule can take a site offline.