Redirecionamentos JavaScript

O que é um redirecionamento JavaScript, como o pipeline de renderização do Google o trata de forma diferente de um 301 no servidor, quando é um último recurso aceitável e como implementar e detectar um — além de onde o meta refresh e a History API se encaixam.

Publicado pela primeira vez: 27 de jun. de 2026 · Última atualização: 3 de ago. de 2026 · Avançado
1 sinal de evidência nesta página

Um redirecionamento JavaScript envia usuários e rastreadores para uma nova URL com código no lado do cliente (window.location.replace() ou .href). É o tipo de redirecionamento menos confiável porque o Google só o vê após a renderização — que pode ser atrasada ou falhar completamente, sem um prazo fixo em ambos os casos. A ordem oficial de preferência do Google é no servidor (301/302/307/308) → meta refresh → JavaScript, e seus documentos dizem claramente: use redirecionamentos JS apenas se você não puder fazer os outros dois. Uma vez que o Google interpreta um com sucesso, o destino se torna um sinal de canonicalização — mas isso não é uma garantia comprovada de PageRank idêntico ou resultados de ranqueamento em comparação a um 301, então trate-o como último recurso, não como uma substituição equivalente. Use-os em plataformas restritas sem acesso ao servidor, para páginas de erro SPA que apontam para um 404 real, e pouco mais. Se você precisar usar um, use window.location.replace() no <head>, remova a URL de origem do seu sitemap e aponte links internos para o destino final. Meta refresh é um redirecionamento separado no nível de HTML, e history.pushState()/replaceState() não são redirecionamentos.

«> TL;DR — A JavaScript redirect is a client-side redirect (window.location.replace(),

.href, .assign()) that Google only processes after rendering — phase three of crawl → render → index. A server-side 301 is seen at crawl time; a JS redirect waits on the render queue, and Google gives no fixed timeline for that wait — it can be quick or it can take a long while, and rendering can fail outright. Google’s documented preference order is server-side → meta refresh → JavaScript, and the docs say to use JS redirects only when you can’t do the other two. Once Google successfully interprets one, the target becomes a permanent canonicalization signal — even Google used them on their own blog when nothing else worked — but that’s not documented proof of identical PageRank or ranking outcomes to a 301, so they’re a last resort, not a spam signal. The legitimate uses are constrained platforms with no server config and SPA error pages that point at a real 404. Implement with window.location.replace() in the <head>, drop the source from your sitemap, repoint internal links, and confirm Googlebot can fetch the JS. Meta refresh is HTML-level (0s = permanent, any delay = temporary), and history.pushState()/replaceState() aren’t redirects at all. » (Tradução) (Síntese localizada do trecho vinte e dois, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«## What counts as a JavaScript redirect » (Tradução) (Síntese localizada do trecho vinte e três, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«Script navigation depends on rendering and execution, so it is not protocol-equivalent to an HTTP redirect. Evidência desta afirmação Primary standard or official documentation supporting the adjacent article claim. Escopo: Protocol semantics and Search behavior are kept separate; no indexing, ranking, or migration-timing guarantee is inferred. Confiança: alta · Verificado: Google: JavaScript redirects Processing is possible, not an exact-timing or indexing guarantee. Evidência desta afirmação Primary standard or official documentation supporting the adjacent article claim. Escopo: Protocol semantics and Search behavior are kept separate; no indexing, ranking, or migration-timing guarantee is inferred. Confiança: alta · Verificado: Google: Redirects and Search » (Tradução) (Síntese localizada do trecho vinte e quatro, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«A JavaScript redirect navigates the browser to a new URL with client-side code. The common methods, and how they differ: » (Tradução) (Síntese localizada do trecho vinte e cinco, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«- window.location.replace("url") — navigates and removes the original URL from session history. This is the one to use: the back button skips the redirect source instead of bouncing the user straight back.

  • window.location.href = "url" — navigates but keeps the original in history, so the back button returns to the redirecting page (and can create a loop). document.location.href and window.location.assign("url") behave the same way.
  • history.pushState() / history.replaceState() — not redirects. They rewrite the address bar without any navigation or HTTP signal, so crawlers don’t treat them as redirects. SPAs use them for in-app URL changes; they need real <a href> links (or actual navigations) to be crawlable. » (Tradução) (Síntese localizada do trecho vinte e seis, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«The dividing line that matters: .replace(), .href, and .assign() all trigger a real document navigation (the difference between them is only what happens to session history), while pushState()/replaceState() never navigate at all — they touch history state and the address bar and nothing else. None of the four is an HTTP 301; “redirect” here is shorthand for client-side navigation, not a status code. » (Tradução) (Síntese localizada do trecho vinte e sete, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«Meta refresh (<meta http-equiv="refresh" content="0;url=...">) is often lumped in with JS redirects, but it’s an HTML directive parsed before JavaScript runs — a separate, more reliable category, covered below. » (Tradução) (Síntese localizada do trecho vinte e oito, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«## How Google processes a JavaScript redirect » (Tradução) (Síntese localizada do trecho vinte e nove, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«This is the crux. Google’s pipeline runs in stages, and a JS redirect and a server-side redirect get caught at different ones: » (Tradução) (Síntese localizada do trecho trinta, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«1. Crawl — Googlebot fetches the URL and reads the raw HTML. A server-side 301/302/307/308 is seen right here. 2. Render queue — pages that return 200 wait to be rendered. Google’s docs note the page “may stay on this queue for a few seconds, but it can take longer than that.” Google doesn’t publish a fixed service-level timeline beyond that, so treat the wait as unpredictable — it can be quick, or it can drag — rather than assuming any specific number of days or weeks. 3. Render + index — headless Chromium runs the JavaScript. This is the first moment a JS redirect exists as far as Google is concerned. » (Tradução) (Síntese localizada do trecho trinta e um, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«The same idea I make on Crawling and in JavaScript SEO applies here: rendering is a separate step from fetching, and anything that depends on it inherits that delay and that risk. » (Tradução) (Síntese localizada do trecho trinta e dois, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«And the risk is real. Google: “While Google attempts to render every URL Googlebot crawled, rendering may fail for various reasons. This means that if you set a JavaScript redirect, Google might never see it if rendering of the content failed.” (Google Search Central) During the window before the redirect is processed — and forever, if rendering fails — Google may keep the empty source page in its index. » (Tradução) (Síntese localizada do trecho trinta e três, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«## Google’s official preference order » (Tradução) (Síntese localizada do trecho trinta e quatro, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«The redirects documentation lays out a hierarchy from most to least reliable: » (Tradução) (Síntese localizada do trecho trinta e cinco, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«1. Server-side redirects — 301/308 (permanent), 302/307 (temporary). Best for everything: seen at crawl time, unambiguous. 2. Meta refresh — HTML-level. A 0-second meta refresh is treated as a permanent redirect (like a 301); any delayed meta refresh is treated as temporary. 3. JavaScript redirects — last resort. » (Tradução) (Síntese localizada do trecho trinta e seis, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«Google’s words: “Only use JavaScript redirects if you can’t do server-side or meta refresh redirects.” Permanent redirects pass the canonical signal to the target; temporary ones keep the original in results. (How that interacts with canonical selection is over on Canonicalization.) » (Tradução) (Síntese localizada do trecho trinta e sete, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«## Does link equity pass through? » (Tradução) (Síntese localizada do trecho trinta e oito, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«Google’s own redirects documentation lists JavaScript location navigation among its permanent redirection methods, and says the target becomes the canonicalization signal once Google has interpreted it — so the flat “JS redirects don’t pass PageRank” claim is false. What the documentation doesn’t establish is that the outcome is identical, immediate, or as reliable as a server-side 301 — it describes the canonical signal, not a guarantee of matching PageRank flow, ranking, or timing. The honest framing: a 301 passes the signal at crawl time with near-certainty; a JS redirect passes it only if and when rendering succeeds, and Google doesn’t promise the result will match a 301’s outcome one-for-one. That gap — not lost equity — is the real cost of choosing JavaScript. » (Tradução) (Síntese localizada do trecho trinta e nove, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«This is also why JS redirects aren’t a penalty trigger on their own. They only become a spam problem when they’re used for cloaking — showing crawlers one page and redirecting users to something different, or sending mobile users to an unrelated domain. Google’s sneaky redirects policy is about that intent, not the technique. » (Tradução) (Síntese localizada do trecho quarenta, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«## When a JavaScript redirect is the right tool » (Tradução) (Síntese localizada do trecho quarenta e um, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«There are legitimate cases: » (Tradução) (Síntese localizada do trecho quarenta e dois, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«- Constrained platforms. Some shared hosting, CDN, or CMS setups give you no access to server-side redirect rules. A JS redirect is a valid fallback — and notably, Google used JS redirects on their own Webmaster blog because, as Gary Illyes put it, “that was the only thing we could use for 1:1 redirects, and it works on Google” (OnCrawl).

  • SPA error handling. Google explicitly endorses this: “Use a JavaScript redirect to a URL for which the server responds with a 404 HTTP status code.” (Google Search Central) A single-page app that resolves a bad route can redirect to a real 404 endpoint so Google processes the error correctly instead of indexing a soft 404. » (Tradução) (Síntese localizada do trecho quarenta e três, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«For permanent URL migrations, this is not the tool — use a 301. I make the same point in site migrations: JavaScript redirects are a last resort, and Google may never see them. » (Tradução) (Síntese localizada do trecho quarenta e quatro, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«## Static site generators: the Hugo aliases trap » (Tradução) (Síntese localizada do trecho quarenta e cinco, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«A common surprise: Hugo’s aliases: frontmatter has historically generated meta refresh HTML pages, not server-side 301s — and other static generators have done similar things by default. Generator defaults change between versions, so check your current deployed version’s actual output rather than assuming; if aliases: isn’t giving you 301s, you need platform-level redirect rules (Netlify _redirects, Cloudflare Workers, Vercel vercel.json) plus (on Hugo) disableAliases: true. I cover this in detail in Hugo SEO. » (Tradução) (Síntese localizada do trecho quarenta e seis, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«## Implementation best practices » (Tradução) (Síntese localizada do trecho quarenta e sete, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«If a JavaScript redirect is genuinely your only option: » (Tradução) (Síntese localizada do trecho quarenta e oito, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«- Use window.location.replace(), not .href. As Search Engine Journal puts it, JS redirects “typically use window.location.replace() function rather than window.location.href to avoid UX redirect loops” (SEJ).

  • Put it in the <head>, not the <body>. Browsers parse HTML sequentially and run scripts as they hit them, so “position JavaScript redirects in the <head> tag rather than <body> to minimize delay” (OnCrawl).
  • Redirect to the final destination in one hop. A JS redirect to a page that itself 301s elsewhere makes a chain; chains waste crawl budget and can surface in GSC as a redirect error.
  • Remove the source URL from your XML sitemap. Sitemaps should list canonical, indexable URLs — not redirecting ones.
  • Repoint internal links at the destination, so they don’t route through the redirect at all.
  • Make sure Googlebot can fetch the JS. If the redirect lives in an external script blocked by robots.txt, Google can’t render it and won’t see the redirect. » (Tradução) (Síntese localizada do trecho quarenta e nove, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«## How to detect JavaScript redirects » (Tradução) (Síntese localizada do trecho cinquenta, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«They don’t announce themselves like a 301 in a header, so you have to render: » (Tradução) (Síntese localizada do trecho cinquenta e um, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«- A crawler with JS rendering on. OnCrawl recommends crawling with “JavaScript rendering enabled (5-second timeout minimum)”; Screaming Frog and Ahrefs Site Audit can both render. Without rendering, a JS-redirecting page just looks like a normal 200.

  • Chrome DevTools. The Network tab (with “Preserve log”) shows the client-side navigation; the Redirect Path extension flags it too.
  • In Search Console, a successfully processed JS redirect shows up under Page with redirect — the same status as any redirected URL, which is normal for non-canonical sources. That label isn’t guaranteed on any given check, though: it reflects whatever Google fetched, rendered, interpreted, and canonicalized at the sampled moment, so a URL can show a different status (or no redirect status yet) between checks without that being an error on your end. » (Tradução) (Síntese localizada do trecho cinquenta e dois, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«## What I’d actually do » (Tradução) (Síntese localizada do trecho cinquenta e três, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

«Server-side first, every time. Meta refresh (0-second) when you can edit HTML but not server config. JavaScript only when both are off the table — and then with window.location.replace() in the <head>, a clean sitemap, and a check that the redirect actually renders for Googlebot. For anything permanent or high-value, the extra reliability of a 301 is worth almost any effort to obtain. » (Tradução) (Síntese localizada do trecho cinquenta e quatro, parte um: o texto-fonte foi preservado para conferência na revisão nativa.)

Adicionar uma nota de especialista

Fixar uma citação de especialista

É uma pessoa nova? Crie o perfil não reivindicado dela em /admin/experts/ → Fixar uma citação de especialista primeiro.