JavaScript Redirects Are Leaking PageRank to Nowhere
On this page
If you moved a page with a JavaScript redirect and the old URL is still indexed on its own months later, the redirect may never have reached Google. Google’s documentation on redirects lists a JavaScript location redirect among the redirect types it treats as permanent, but it also says to use JavaScript redirects only if you can’t do server-side or meta refresh redirects, because rendering may fail and Google might never see the redirect. When that happens, the old URL stays a live page with its own links and its own index entry, and the move you made never registers as a move. Put the redirect in the HTTP response instead, where it doesn’t depend on rendering at all.
What Google says about JavaScript redirects
The redirects documentation makes three points:
- Google executes the script after crawling. It interprets and executes JavaScript using the Web Rendering Service once crawling of the URL has completed.
- Rendering can fail. Google attempts to render every URL Googlebot crawled, but rendering may fail for various reasons, and then Google might never see a JavaScript redirect.
- Server-side comes first. Google recommends a permanent server-side redirect whenever possible, a meta refresh if server-side redirects aren’t possible, and JavaScript only after that.
The documented JavaScript redirect is a location assignment in a script block in the HTML head. A navigation that fires later inside application code, after data loads or a component mounts, has even more that must go right before anything redirects.
Check what Google recorded
Start with the old URL:
Request it without a browser. A command-line request shows the raw response:
curl -I https://example.com/old-url
A 301 or 308 status with a Location header is a server-side redirect. A 200 means the server answers the old URL as a live page, and any redirect happens in the page itself, through a meta refresh or a script.
Inspect it in Search Console. Run the old URL through the URL Inspection tool. If Google treats it as an indexed page of its own, possible reasons include a redirect that never registered, other signals keeping the old URL canonical, or a recrawl that hasn’t happened yet. The raw response is where to start: a 200 points to the first.
Put the redirect in the response
Static and serverless hosts still answer every request with an HTTP response, so the redirect can live in that response instead of in your scripts.
Next.js. The redirects configuration in next.config.js takes source, destination and permanent. With permanent: true it uses the 308 status code, and the documentation says redirects are checked before the filesystem, which includes pages and public files. Client-side navigation such as router.push runs in the browser after the page loads, so keep it for in-app navigation, not for a permanent URL change.
Vercel. Vercel’s redirects documentation covers redirects in framework config or vercel.json, and recommends the 307 or 308 status codes to avoid ambiguity with non-GET methods. Watch one trap it describes: a hostname redirect published as a firewall rule from the dashboard is a temporary 307, and the documentation points to a configuration rule when you need a permanent redirect.
Netlify. Netlify’s redirects documentation uses a _redirects file or netlify.toml. The status is 301 by default, but force is false by default: if content still exists at the old path, Netlify serves it instead of redirecting. If your build still outputs the old page, force the rule with !.
A traditional server. Google’s redirects documentation notes that server-side redirects require access to the server configuration files, such as .htaccess on Apache, or setting redirect headers with server-side scripts.
301 or 308
Google’s documentation says the 301 and 308 status codes mean a page has permanently moved, so either works for a page move. Next.js explains its choice of 308: browsers traditionally changed the request method of a 301 to GET, and 308 preserves the method. For an ordinary page, that difference doesn’t matter. What matters is using a permanent code for a permanent move; Google’s documentation groups 302, 303 and 307 as temporary.
After the fix
Once the old URL returns a permanent redirect, update your internal links to point at the new URL directly, so your own pages don’t depend on the redirect. Then run the URL Inspection live test on the old URL to confirm Google gets the redirect, and give Google time to recrawl the old URL before judging the result.
If you can’t change the response, an instant meta refresh is the next option: Google Search interprets instant meta refresh redirects as permanent redirects, and it doesn’t depend on running your application’s JavaScript.
Frequently asked questions
Do JavaScript redirects lose PageRank?
Google’s site move guide says 301 and other permanent redirects don’t cause a loss in PageRank, and its redirects documentation lists a JavaScript location redirect among the permanent types. The documented risk of a JavaScript redirect is different: if rendering fails, Google might never see it, and the old URL stays a page of its own.
Does Google ever follow a JavaScript redirect?
Yes, when rendering succeeds; the documentation lists a JavaScript location redirect among the permanent types. It also tells you to use one only when server-side and meta refresh redirects aren’t possible.
Is a meta refresh a safe alternative?
An instant meta refresh is interpreted as a permanent redirect, and Google puts it ahead of JavaScript in its order of preference when server-side redirects aren’t possible. A delayed meta refresh is interpreted as temporary.