Test rewrite rules before they take a site down
Paste your directives, enter a URL, and get a line-by-line trace of what matched and what did not. Including the two things that break most rules: the stripped leading slash, and the fact that L does not mean stop.
Your .htaccess rules
Nothing is uploaded. The whole simulation runs in your browser.
We cannot see your server’s disk, so filesystem tests use these assumptions. Steps that depend on one are marked in the trace.
External redirect — 301
/blog/hello-world
1 pass through the ruleset · the address bar does not change
Evaluation trace
1 of 1 steps matched- L13RedirectMatch 301 ^/old-blog/(.*)$ /blog/$1pass 1
"/old-blog/hello-world" matches /^/old-blog/(.*)$/
/old-blog/hello-world/blog/hello-world
In a .htaccess file Apache strips the leading slash before matching, so a request for /blog/post is tested against blog/post. That is why ^/blog never matches in a root .htaccess and ^blog does — the single most common reason a rule that looks right does nothing. The trace shows the stripped form at every step.
Four things that break most rewrite rules
- 1
The leading slash is already gone
In a .htaccess file Apache strips the directory prefix before matching, so /blog/post is tested against "blog/post". A pattern of ^/blog can never match. The same rule works in a server or vhost config, which is where most copied examples come from — and why the copy fails.
- 2
L does not mean stop
It ends the current pass. If the URL changed, Apache restarts the entire ruleset from the top with the new URL. That is how a file where every rule carries L still produces an infinite loop. END, from Apache 2.4, is the flag that actually stops everything.
- 3
Conditions are evaluated after the rule matches
RewriteCond lines are written above the rule and read as prerequisites, but Apache tests the RewriteRule pattern first and only then evaluates the conditions. A rule whose pattern never matches means its conditions never run, which makes debugging by adding more conditions futile.
- 4
A rewrite is not a redirect
Without an R flag the change is internal — different content, same address bar, invisible to search engines. With R it becomes a 301 or 302 that transfers signals to the destination. Confusing the two produces either a redirect you did not want or a canonicalisation you never got.
What this cannot know
It simulates the directives you paste, in isolation. Your real server also has server and virtual-host configuration, other modules, rules inherited from parent directories, and an actual filesystem. Use this to reason about your logic and catch the common mistakes, then verify on staging before it reaches production.
Frequently asked questions
Why does my rule starting with ^/ never match?
Because .htaccess runs in a per-directory context, and Apache strips the directory prefix — including the leading slash — before matching. A request for /blog/post is tested against "blog/post". So ^/blog can never match in a root .htaccess, while ^blog matches fine. This one detail accounts for more broken rewrite rules than everything else combined, largely because the same rule does work when placed in a server or virtual-host config, which is where most copied examples come from.
Does the L flag mean "stop"?
Not quite, and the difference matters. L ends the current pass through the ruleset. In a .htaccess file, if the URL was rewritten, Apache then starts the whole ruleset again from the top with the new URL — which is exactly how infinite loops happen despite an L flag on every rule. The END flag, added in Apache 2.4, is the one that genuinely stops all processing. If you have a loop you cannot explain, this is usually why.
Why can the tool not check whether a file exists?
Because it has no access to your server's filesystem, and nothing that runs in a browser could. Conditions like RewriteCond %{REQUEST_FILENAME} !-f depend entirely on that. Rather than guess, the tool lets you state the assumption and marks every step that depends on it. Toggle "path is a real file" and watch the classic front-controller rule flip — that toggle is the whole behaviour of a pretty-URL setup in one checkbox.
What is the difference between a rewrite and a redirect?
A rewrite is internal: Apache serves different content and the visitor's address bar never changes. A redirect sends a 301 or 302 back to the browser, which then requests the new URL, and the address bar updates. For SEO they are entirely different — a rewrite is invisible to search engines, while a redirect transfers signals to the destination. The R flag, or an absolute URL in the substitution, is what turns a rewrite into a redirect.
Does this handle RewriteCond OR chains correctly?
Yes. Conditions default to AND; the [OR] flag chains a condition with the next one so either can satisfy that link. The trace shows each condition evaluated individually with the value it was tested against, so a chain that behaves unexpectedly is visible rather than inferred. Note that conditions are only evaluated after the RewriteRule pattern matches — a common misreading, since they are written above the rule.
Will the results exactly match my server?
Close, not identical. This simulates the mod_rewrite directives you paste in isolation. A real server also has server-level and virtual-host configuration, other modules, inherited rules from parent directories, and its actual filesystem — any of which can change the outcome. Treat this as a way to reason about your logic and catch the common mistakes before deploying, then verify on a staging environment.
Should I use .htaccess at all?
If you can put the rules in your server or virtual-host configuration instead, do — Apache re-reads .htaccess on every request to every directory in the path, which costs real performance. On shared hosting you usually have no choice, and that is what .htaccess exists for. Either way, redirect chains are worth auditing: every extra hop costs crawl budget and a little authority, and long chains accumulate quietly over years of site migrations.
Related tools and reading
Migrations are where rankings go to die.
Not because redirects are hard, but because nobody maps the old URLs before the new site ships. If one is coming, the redirect plan is the part worth getting reviewed.
Get a Free Technical Audit