JavaScript Redirect
A JavaScript redirect sends the visitor to a new URL from script (`location.href`, `location.replace`, or `location.assign`) after the original page loads. It's a client-side redirect, invisible at the HTTP layer and only visible once JavaScript executes.
Two costs: crawl latency and user experience
Google follows JavaScript redirects, but only after rendering the page, a second-wave process compared to an HTTP 3xx redirect it can act on instantly. Users pay twice: the full page loads, then navigation fires.
The APIs differ in back-button behaviour. location.href and location.assign add a history entry (the back button returns to the redirect source). location.replace overwrites it. For redirect detection, browsers see the actual navigation; fetch-based checkers see only the original page. This is why redirect chains mysteriously differ between what the browser shows and what a tool reports.
When it fires and who sees it
A JavaScript redirect executes after the HTML is parsed and rendered. The browser loads the initial page in full, then runs the script and navigates to the new URL. Google's crawler must render the page to discover the redirect, making it a render-time signal, not an HTTP-level one. Search engines treat JS redirects as weaker than server-side 3xx redirects precisely because they require rendering.
For detection: only live browser observation sees JS redirects. Fetch-based tools (most SEO checkers) see only the original page, which is why tool outputs and browser behaviour often mismatch.
Google doesn't ban it: performance does
JavaScript redirects aren't "banned" by Google. Crawlers follow them if they render. The issue is cost and user experience, not a ranking penalty.
Delayed or conditional JS redirects are legitimate in some flows: post-login bounces, SPA route guards, gradual migrations. But if you're redirecting everyone to a different URL unconditionally, a server-side 3xx is faster and cheaper. The problem isn't the legality; it's the wasted render cycle.
Simple redirects: use the server instead
The basic location.href redirect:
location.href = "/new-url";
Better: location.replace (skips back-button pollution):
location.replace("/new-url");
A conditional redirect (mobile users only):
if (window.innerWidth < 768) {
location.replace("/mobile-home");
}
For production: prefer a server-side redirect (HTTP 301 or 302). If JavaScript is mandatory (SPAs, client-side routing), use location.replace to avoid back-button confusion.
How Scalpel shows it
Scalpel Redirects detects JavaScript redirects by observing live navigation with a client_redirect qualifier. If the navigation doesn't match a meta-refresh target, it flags it as a "JS redirect" and renders it as a connector linking redirect chains into one path. Combined with HTTP hops, you see the whole route: server 301s, then a JS hop, all rendered as one linked path.