Meta Refresh Redirect
What a meta refresh redirect is, why it sits between server-side and JavaScript redirects in Google's order of preference, instant versus delayed refreshes, and why it is discouraged.
A meta refresh redirect is an HTML <meta http-equiv="refresh"> tag (or the equivalent HTTP Refresh header) — not an HTTP status code. The server returns a normal 200 and the browser only acts on the redirect once the page is treated as loaded, per the HTML Standard, which is exactly why it's weaker than a server-side redirect. An instant one (content="0") is read by Google as permanent, like a 301; a delayed one (content greater than 0) as temporary, and delay is the trait tied to old doorway-page spam. John Mueller says it 'should just work' but isn't recommended for two reasons: it keeps the page in browser history 'afaik' (his words), and Google has to load and parse the page before it can even see the redirect. Use it only as a last resort when you genuinely have no server access, prefer the 0-second version, and swap in a real 301 the moment you can.
TL;DR — A meta refresh redirect is a line of HTML — a
Evidence for this claim Google supports instant and delayed meta refresh redirects but recommends server-side permanent redirects when possible. Scope: Google redirect processing and implementation preference. Confidence: high · Verified: Google Search Central: Redirects Evidence for this claim Timed redirects can create accessibility problems, particularly when users cannot control the time limit. Scope: WCAG timing guidance; not a search-ranking claim. Confidence: high · Verified: W3C WCAG: Timing Adjustable<meta http-equiv="refresh">tag — that tells the browser to jump to another URL after the page loads. It is not an HTTP status code like a 301. Your server returns a normal page first, then the browser does the redirect. It works, but it’s slower and clumsier than a real server-side redirect, so use it only when you have no other option.
What a meta refresh redirect is
Most redirects happen on the server. You ask for a URL, and before you get any
page at all, the server answers “that moved — go here instead” (that’s a 301 or a
302). A meta refresh works completely differently. The server sends back a
normal, working page (a 200 OK), and inside that page’s HTML is an instruction
telling the browser to go somewhere else:
<meta http-equiv="refresh" content="0;url=https://example.com/newlocation">That tag lives in the <head> of the page. The number before the semicolon is how
many seconds to wait; the url= part is where to send the visitor. Because it’s
the browser — not the server — that acts on it, this is called a client-side
redirect.
Instant vs. delayed
There are really two flavors, and the difference is just that number:
- Instant —
content="0;url=...". The browser jumps as soon as the page finishes loading. This is the version you want if you have to use meta refresh at all. Google treats it like a permanent redirect (similar to a 301). - Delayed —
content="5;url=..."(any number bigger than 0). The browser shows the page for a few seconds, then jumps. Google treats this as a temporary redirect, and the delay is the thing that historically got meta refresh a bad, spammy reputation.
Why people say to avoid it
A meta refresh does work — but it’s weaker than a server redirect because the browser only acts on the redirect instruction once the page is treated as finished loading — the HTML Standard’s own trigger condition — not before. A server-side redirect happens instantly, before any page loads at all. Google’s own guidance ranks server-side redirects first, meta refresh in the middle, and JavaScript redirects last.
So the simple rule: use a real 301 if you possibly can. Reach for a meta
refresh only when you’re on a host where you truly can’t set up a server redirect
(some static hosting setups) — and even then, use the instant (0) version and
switch to a proper 301 the moment you’re able to.
Want the full picture — Google’s exact wording, the accessibility angle, and how to detect these on your site? Switch to the Advanced tab.
TL;DR — A meta refresh is an HTML
Evidence for this claim Google supports instant and delayed meta refresh redirects but recommends server-side permanent redirects when possible. Scope: Google redirect processing and implementation preference. Confidence: high · Verified: Google Search Central: Redirects Evidence for this claim Timed redirects can create accessibility problems, particularly when users cannot control the time limit. Scope: WCAG timing guidance; not a search-ranking claim. Confidence: high · Verified: W3C WCAG: Timing Adjustable<meta http-equiv="refresh">tag (or the server-injectedRefreshheader), not a3xxstatus code — the server returns200and the browser navigates only after the page has completely loaded. Instant (content="0") reads as permanent to Google, like a 301/308; delayed (> 0) reads as temporary. It sits between server-side and JavaScript redirects in Google’s reliability order because of that full-page-load dependency. Mueller: it “should just work,” but isn’t recommended (back-button history + parse-time cost). Use it only when you genuinely lack server access, prefer0, pair it withrel=canonicaland a visible fallback link, and replace it with a real 301 as soon as you can.
It’s not a status code
This is the one thing to get right. A meta refresh is not an HTTP 3xx
response. The server returns an ordinary 200 OK with a full page body; sitting
in that page’s <head> is an HTML directive that the browser acts on after the
page loads:
<!-- Instant: treated by Google as permanent -->
<meta http-equiv="refresh" content="0;url=https://example.com/newlocation">There’s a server-side equivalent — the Refresh HTTP header — which does the same
thing but is injected by server code instead of sitting in the markup:
HTTP/1.1 200 OK
Refresh: 0; url=https://www.example.com/newlocationNote that even the header version returns 200, not a 3xx. Either way, this is a
client-side redirect: the browser performs the navigation, not the server.
Instant vs. delayed — Google’s split
Google draws the line at the number of seconds. In its
Redirects and Google Search
docs it says it “differentiates between two kinds of meta refresh redirects”:
- Instant (
content="0") — “Triggers as soon as the page is loaded… Google Search interprets instantmeta refreshredirects as permanent redirects.” So for canonicalization it’s in the same bucket as a 301/308: Google follows it and uses it as a signal that the target should be canonical. - Delayed (
contentgreater than 0) — “Triggers only after an arbitrary number of seconds… Google Search interprets delayedmeta refreshredirects as temporary redirects.” Like a 302/303/307, the target might still be indexed via other signals, but the redirect itself isn’t taken as a permanent-move signal.
My own redirect ordering in the Ahrefs guide to 11 types of redirects reflects this: for permanent moves I rank them 308 / 301 → meta refresh 0 → JavaScript → crypto, and delayed meta refresh drops to the temporary tier alongside 302/303/307.
Where it sits in Google’s order of preference
Google’s redirect docs literally publish a preference table, “ordered by how
likely Google is able to interpret [the redirect] correctly.” For permanent
redirects the order is: HTTP 301 → HTTP 308 → meta refresh (0 seconds) →
JavaScript location → crypto. Meta refresh is the middle rung — below
server-side, above JavaScript.
Google is explicit about both boundaries. On the top boundary: “If server-side
redirects aren’t possible to implement on your platform, meta refresh redirects
may be a viable alternative.” On the bottom boundary: “Only use JavaScript
redirects if you can’t do server-side or meta refresh redirects.” That’s the
whole ladder in two sentences — and it matches the framing already in the
redirects hub, which notes that JS
and delayed meta-refresh are weaker because they depend on rendering.
Two different “orders” — don’t conflate them
Here’s a subtlety that trips up developers. MDN publishes a
different ordering
for redirects — but it’s about browser execution order when several redirect
mechanisms are stacked on one page, not SEO reliability. MDN’s order is: HTTP
redirects first, then JavaScript, then meta refresh last — because “the <meta>
redirect happens after the page is completely loaded, which is after all scripts
have executed.”
So JavaScript “beats” meta refresh in MDN’s timing order, but meta refresh “beats” JavaScript in Google’s reliability order. Both are correct — they answer different questions. MDN is asking “which fires first in the browser?” (synchronous JS runs during load, before the meta refresh’s post-load timer). Google is asking “which am I most likely to interpret correctly for search?” (a meta refresh is read straight from the parsed HTML; a JS redirect needs Google’s separate rendering step to succeed). Keep those axes apart and the apparent contradiction disappears.
Why it depends on the page loading — and why that makes it weaker
A meta refresh can’t fire until the page has completely loaded. Per MDN’s
<meta http-equiv>
reference, “the timer starts when the page is completely loaded, which is after
the load and pageshow events have both fired.” That’s true even for
content="0" — “instant” means zero additional delay after load, not zero
elapsed time. A slow page delays even a 0-second refresh in a way a server-side
3xx never could, because the server sends the redirect before any page loads at
all.
Worth being precise: a meta refresh is not processed at Google’s render (JS
execution) stage the way a window.location redirect is — it’s read directly from
the parsed HTML <head>. Its weakness isn’t the rendering pipeline; it’s the
full-page-load dependency (network completion, render-blocking resources) plus,
for delayed variants, an arbitrary wait.
What the HTML Standard actually specifies
The HTML Standard’s declarative-refresh algorithm is more precise than “waits for the page to load,” and a few of its details matter for auditing and troubleshooting:
- Due time. The refresh becomes due after the document’s completely-loaded time
and, for a
<meta>element specifically, its insertion time — whichever is later — adjusted for user preferences. That’s the spec-level version of “after the page loads”; exactly which network/render events count as “loaded” in a given browser is an implementation detail, not something the Standard itemizes as a universal fetch-and-paint sequence. - Relative URLs. The refresh target is parsed relative to the document’s own
URL, so when you’re auditing one, resolve the absolute destination rather than
trusting the literal
url=string — a relative path can point somewhere other than it looks like at a glance. - First one wins. Once a document is already marked to declaratively refresh,
the algorithm ignores any later refresh instruction on that page. Two conflicting
<meta refresh>tags (or a tag plus aRefreshheader) isn’t a fallback plan — it’s an authoring defect, and only the first one takes effect. javascript:targets are rejected. If the parsed target uses thejavascript:scheme, the algorithm returns without navigating.- It isn’t guaranteed to fire. The Standard explicitly allows the navigation to be canceled, adjusted by user or user-agent preferences, blocked by a sandboxed document’s automatic-features restriction, exposed through the browser’s own UI, or simply not performed. Don’t treat “it’ll redirect” as an absolute.
- History handling. The Standard specifies replace history handling for the refresh navigation — meaning the spec text has the browser replace the current history entry rather than add a new one. That’s worth flagging against the “keeps the old page in browser history” framing below: it’s what a named Google spokesperson reported about real-world behavior in 2018, and it may still hold in practice, but it isn’t what the current spec text itself describes. Treat “meta refresh always leaves the source page in history” as unconfirmed folklore rather than settled behavior — verifying it would take browser/version-specific testing, which is outside what these sources establish.
John Mueller put the “why not recommended” case concisely (relayed by Search Engine Roundtable, 2018): a meta refresh “should just work,” but Google doesn’t recommend it for two reasons — UX (“it keeps the page in browser history, afaik” — his own hedge) and processing time (Google has to parse the page to even see the redirect). “Once processed, it’s just like a redirect.” That’s a more useful explanation than the usual “it’s old and spammy,” because it names concrete, non-spam costs — even if the history half is a reported observation rather than a documented spec guarantee (see above).
Why it’s discouraged — the historical baggage
Separate from Mueller’s UX/parse-time reasons, meta refresh carries a reputation. In the 2000s web-spam era it was a common doorway-page vehicle: a page ranks for a query, then near-instantly meta-refreshes the visitor to a different, less relevant destination — showing search engines and users effectively different outcomes. That’s the origin of the “spammy” label. It’s worth being accurate here: no current Google spam-policy page names “meta refresh” explicitly; the policies define “sneaky redirects” and “doorway” abuse as general categories that meta refresh historically served as a mechanism for. Treat this as historical/industry context, not an explicit current policy citation.
There’s also a concrete, non-spam failure mode Mueller flagged in a 2018 hangout (via Search Engine Journal): a site that meta-refreshed listing pages to a shared payment page. “So if you do this across your pages there’s a big chance we’ll follow this redirect and think ‘Oh, this payment page is actually what you want to have indexed and not the actual content.’” Mass-refreshing many source pages to one generic destination can get the destination indexed instead of your content.
None of that makes an isolated, legitimate meta refresh a penalty risk. Google’s own current docs call it “a viable alternative” when server-side redirects aren’t possible. The risk is pattern and intent, not the mechanism.
Evidence for this claim Google says meta refresh can be a viable alternative when server-side redirects are not possible, while permanent server-side redirects are recommended whenever possible for a URL move. Scope: meta refresh and HTTP Refresh interpretation Confidence: high · Verified: Redirects and Google SearchAccessibility: the same instant-vs-delayed split
The SEO framing has an almost exact twin in accessibility guidance — with one
qualification worth stating up front: W3C’s WAI techniques
are, in their own words, examples of ways to meet WCAG success criteria, not
mandatory conformance rules. Meeting or missing a specific technique isn’t itself
an automatic pass or fail; the actual requirement is the success criterion (here,
2.2.1 Timing Adjustable). With that said, W3C’s own preference matches the SEO
guidance above: it recommends a server-side redirect first, and where a
client-side redirect is genuinely necessary, its sufficient techniques (H76,
G110) call for no delay (content="0") and a source page whose content is
limited to redirect-related information plus a visible link to the destination.
That’s a narrower bar than “any 0-second refresh automatically passes” — it’s
“zero delay, redirect-only content, and a fallback link” as the documented
sufficient pattern. A delayed meta refresh with no way to pause, extend, or
disable it risks failing 2.2.1, because it can navigate away before a
screen-reader user or someone with low vision has finished reading — but whether a
specific delayed refresh actually fails the criterion is a case-by-case WCAG
evaluation, not something a technique number alone settles. MDN’s
accessibility note
describes the same underlying risk: too-short refresh intervals mean people using
assistive tech “may be unable to read through and understand the page’s content
before being automatically redirected.”
So both a search engine and a standards body land on the same rule: instant is
fine, delayed is risky. That’s a nice bit of reinforcement — and one more reason
to prefer content="0" if you use meta refresh at all.
When it’s a legitimate last resort
Use meta refresh only when you genuinely can’t do a server-side redirect. Real cases where that happens:
- Static hosts with no server config — e.g. GitHub Pages, where you can’t add
.htaccess/nginx rules. - Static-site generators whose “aliases” feature outputs meta refresh, not 301s.
Hugo is a known example — its
aliases:front-matter generates little meta-refresh HTML files, not real server redirects. (More on that in Hugo SEO.) - No-code / website-builder exports and some doc generators that only let you emit static HTML.
If you’re stuck with it, do it well:
- Prefer instant (
content="0") over any delay — permanent signal, and it clears the accessibility bar. - Pair it with
rel="canonical"pointing at the destination, so the canonicalization intent is explicit even before Google processes the refresh. - Include a visible, clickable fallback link in the body for the rare browser or assistive-tech setting where auto-refresh is disabled.
- Don’t stack it into a redirect chain — if the meta-refresh page’s URL later also gets a server-side redirect layered on, you’ve built a chain (see redirect chains).
- Replace it with a real 301 the moment you have server access. Meta refresh is a bridge, not a destination.
Detecting meta refresh on your site
Crawlers surface these, usually as a low-to-medium severity flag rather than a
critical error — Screaming Frog, Sitebulb, Ahrefs Site Audit, and Semrush all
report them. For an isolated handful of URLs it’s a “fix when convenient” item, not
an emergency; site-wide use on important pages is where it becomes worth
prioritizing. To check a single URL by hand, view source or curl the page and
look for http-equiv="refresh" in the <head> (there are ready snippets in the
Scripts lens).
Be careful with claims in either direction on link equity. The Ahrefs help-center line that meta refresh “does not pass much or any link juice” is worth questioning — Google’s redirect table classifies an instant meta refresh in the same permanent-redirect interpretation bucket as a 301, which is a signal about how Google reads and canonicalizes the redirect, not a stated promise about identical PageRank, link-equity, or ranking transfer. Neither Google’s redirects documentation nor the HTML Standard makes an explicit claim about equity parity between a meta refresh and a 301 — so treat “it passes the same value as a 301” and “it passes little or none” as equally unverified beyond what’s actually documented: Google classifies it as permanent, and processes it after it loads the page.
A meta-refresh source page still has its own HTTP response and its own HTML
document — auditing one shouldn’t stop at reading the refresh tag. Check, in order:
the source URL’s HTTP status and response headers (including a possible Refresh
header); the raw HTML versus what a browser actually parses; which refresh
directive is the first (and therefore effective) one, and its resolved absolute
target; how Google’s redirect table would classify it (instant/permanent vs.
delayed/temporary); the source page’s own canonical tag, robots directives, and
indexability; the final destination’s response; whether the redirect is
cancelable, controllable, or skipped by user/browser preferences; cache and history
behavior in the specific named browser and version you’re testing (not as a
universal claim); internal links still pointing at the source; and, last, your plan
to replace it with a server-side redirect. The Checklists and Scripts lenses on
this page break these into concrete steps and commands.
AI summary
A condensed take on the Advanced version:
- Not a status code. A meta refresh is an HTML
<meta http-equiv="refresh">tag (or theRefreshHTTP header). The server returns200; the browser navigates after the page fully loads. It’s a client-side redirect. - Instant vs. delayed.
content="0"= Google treats it as permanent (like a 301/308).content > 0= temporary (like a 302/303/307), and delay is the trait tied to old doorway-page spam. - Middle of Google’s order. Server-side → meta refresh → JavaScript → crypto. Google: “If server-side redirects aren’t possible… meta refresh… may be a viable alternative,” and “Only use JavaScript redirects if you can’t do server-side or meta refresh redirects.”
- Two different “orders.” MDN’s execution order puts JS before meta refresh (meta refresh fires post-load, after scripts). Google’s reliability order puts meta refresh above JS. Both correct — different questions.
- Why weaker: the HTML Standard’s due-time algorithm holds it until the page is
loaded — true even for
0— and the navigation can be canceled or skipped by user/browser preferences; it’s not a 100% guarantee. Mueller: it “should just work” but isn’t recommended (browser history “afaik” + parse-time cost) — the history point is his reported observation, not something the current spec text itself states (the Standard specifies replace history handling). - Link equity: unverified either way. Google’s table groups instant meta refresh with 301s for interpretation, not a documented PageRank/equity-parity promise — don’t over-claim in either direction.
- Accessibility mirrors SEO, with a caveat: W3C prefers server-side redirects too; its sufficient techniques (H76/G110) call for zero delay + redirect-only content + a fallback link — but these are example techniques, not mandatory conformance rules. A delayed refresh with no user control risks failing 2.2.1 Timing Adjustable; whether it actually does is a case-by-case evaluation.
- Use only as a last resort (GitHub Pages, Hugo
aliases, static/no-code hosts). Prefer0, addrel=canonical+ a visible fallback link, avoid chains, and swap in a real 301 as soon as you can.
Official documentation
Primary-source documentation on meta refresh and where it fits.
- Redirects and Google Search — the redirect-preference table, the instant-vs-delayed definition, and the “viable alternative” framing.
- Spam policies for Google web search — defines “sneaky redirects” and “doorway” abuse as general categories (note: does not name meta refresh explicitly).
MDN
<meta http-equiv>— the client-side mechanics: the timer “starts when the page is completely loaded.”RefreshHTTP header — the server-injected equivalent.- Redirections in HTTP — the browser execution order of precedence (distinct from Google’s SEO order).
W3C / WCAG
- H76: Using meta refresh to create an instant client-side redirect — server-side preferred; where that’s not possible, the 0-second, redirect-only-content pattern as a sufficient technique (not a mandatory rule).
- G110: Using an instant client-side redirect — the general (non-HTML-specific) version of the same technique.
- F41: Failure due to using meta refresh with a time-out — how an uncontrolled delayed refresh can fail 2.2.1 Timing Adjustable; a technique/failure page, not itself the conformance requirement.
Quotes from the source
On-the-record statements. Each link is a deep link that jumps to the quoted passage.
Google — Redirects and Google Search docs
- “The following table explains the various ways you can use to set up permanent and temporary redirects, ordered by how likely Google is able to interpret correctly (for example, a server side redirect has the highest chance of being interpreted correctly by Google).” Jump to quote
- “If server-side redirects aren’t possible to implement on your platform, meta refresh redirects may be a viable alternative.” Jump to quote
- “Google differentiates between two kinds of meta refresh redirects: Instant meta refresh redirect: Triggers as soon as the page is loaded in a browser. Google Search interprets instant meta refresh redirects as permanent redirects. Delayed meta refresh redirect: Triggers only after an arbitrary number of seconds set by the site owner. Google Search interprets delayed meta refresh redirects as temporary redirects.” Jump to quote
- “Place the meta refresh redirect either in the <head> element in the HTML or in the HTTP header with server-side code.” Jump to quote
- “Only use JavaScript redirects if you can’t do server-side or meta refresh redirects.” Jump to quote
- “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.” Jump to quote
John Mueller, Google (tweets relayed via Search Engine Roundtable, March 2, 2018)
- “A meta refresh type redirect should just work. We don’t recommend it for 2 reasons: UX (it keeps the page in browser history, afaik) & processing time (we need to parse the page to see it). Once processed, it’s just like a redirect.” Jump to quote
John Mueller, Google (Webmaster Central hangout, July 2018, relayed via Search Engine Journal)
- “So if you do this across your pages there’s a big chance we’ll follow this redirect and think ‘Oh, this payment page is actually what you want to have indexed and not the actual content,’ and in that case we won’t have the content indexed.” Jump to quote
MDN
- “The timer starts when the page is completely loaded, which is after the load and pageshow events have both fired.” Read the doc
- “When possible, use HTTP redirects and don’t add <meta> element redirects.” Read the doc
Which redirect should I use?
Meta refresh is a fallback, not a first choice. Work down from the strongest option you can actually implement.
Choosing a redirect when meta refresh is on the table
Meta refresh myths and mistakes
Common misconceptions, and what’s actually true.
“Meta refresh is an HTTP redirect / a 3xx status code.”
No. It’s an HTML tag (or the Refresh HTTP header) that the browser acts on after
a normal 200 response and a full page load — not a status code the server sends
before any content.
“A 0-second meta refresh fires instantly, before the page even loads.”
No. Per MDN, the timer “starts when the page is completely loaded.” content="0"
means zero additional delay after load, not zero elapsed time. That’s exactly why
Mueller cites “processing time (we need to parse the page to see it)” even for the
instant variant.
“Meta refresh is basically the same as a JavaScript redirect.” Not quite. Both are client-side, but a meta refresh is declared in HTML and read straight from the parsed document, while a JS redirect needs script execution. Google ranks meta refresh above JS for reliability; MDN’s browser execution order ranks synchronous JS before meta refresh. Both are true — they answer different questions.
“Meta refresh doesn’t pass any link equity / PageRank.” Unsupported as stated — but so is the opposite claim. Google’s redirect table puts an instant meta refresh in the same permanent-redirect interpretation bucket as a 301/308, which is about how Google classifies and canonicalizes the signal. Neither Google’s documentation nor the HTML Standard makes an explicit statement about PageRank, link-equity, or ranking parity between the two mechanisms — so don’t assert equivalence either way beyond the documented classification.
“Meta refresh is always spammy and will get my site penalized.” False as a blanket claim. It has a historical doorway-spam association, but a single legitimate use — e.g. on a static host with no server access — is not a spam signal. Google’s current docs call it “a viable alternative.” The risk is pattern and intent (cloaking, mass-redirecting to unrelated content), not the mechanism.
“A few seconds’ delay is a nice UX courtesy, not a real problem.” Mixed. Any delay greater than 0 downgrades it to Google’s temporary treatment, and W3C’s accessibility techniques treat an uncontrollable delay as the pattern to avoid — but a missed technique isn’t automatically a WCAG violation on its own; it still comes down to whether the actual success criterion (2.2.1, Timing Adjustable) is met. “A few seconds to let the user read a message” with no way to pause, extend, or skip it is exactly the pattern that risks failing it.
“My crawler flagged ‘meta refresh tag’ — it’s a critical issue to fix now.” Overstated for isolated cases. Tools like Screaming Frog classify it as a low-severity warning. Worth replacing with a real 301 when you get server access, but not the same urgency tier as broken redirects, loops, or missing indexing signals — unless it’s site-wide or on high-value pages.
If you have to ship a meta refresh — checklist
Use this only after confirming a server-side redirect genuinely isn’t available:
- Confirmed there’s no server-side redirect option (checked hosting
settings,
.htaccess/nginx access, CDN rules, framework config). - Used the instant form —
content="0"— not a delayed one. - The tag is in the
<head>, and theurl=value is the final destination (not another redirect — avoid building a chain). - Added a
rel="canonical"pointing at the destination URL. - Included a visible, clickable fallback link in the body for anyone whose browser/assistive-tech setting disables auto-refresh.
- Destination returns a clean
200(not itself a 404, redirect, or error). - Logged a follow-up to replace it with a real 301 once server access is available.
Auditing meta refresh across a site
- Ran a crawl (Screaming Frog / Sitebulb / Ahrefs Site Audit / Semrush) and exported all URLs flagged as meta-refresh redirects.
- For each flagged URL, checked the HTTP status and response headers
(including a possible
Refreshheader) — not just the HTML. - Identified the first (effective) refresh directive if more than one is
present, and resolved its
url=target to an absolute URL. - Classified it instant vs. delayed to predict Google’s permanent/temporary treatment, and separately checked the source page’s own canonical tag, robots directives, and indexability.
- Checked whether it’s isolated (low priority) or site-wide / on high-value pages (prioritize).
- Looked for the payment-page pattern — many source pages refreshing to one generic destination that could get indexed instead of your content.
- Flagged any delayed refreshes as both an SEO and an accessibility issue.
Meta refresh — cheat sheet
The two variants
| Variant | Syntax | Google treats it as | Accessibility |
|---|---|---|---|
| Instant | content="0;url=..." | Permanent (like 301/308) | Sufficient technique (H76/G110) |
| Delayed | content="5;url=..." (any > 0) | Temporary (like 302/303/307) | Risks failing 2.2.1 (F41 pattern) |
Google’s redirect preference (permanent), strongest → weakest
| Rank | Method | Notes |
|---|---|---|
| 1 | 301 / 308 (server-side) | Best — fires before any page loads |
| 2 | Meta refresh 0 | Read as permanent, but clumsy/slow (needs full load) |
| 3 | JavaScript location | Needs rendering; may never be seen if render fails |
| 4 | Crypto redirect | True last resort; not all bots support it |
Two orderings, don’t conflate
| Question | Order |
|---|---|
| Google — SEO reliability | server-side → meta refresh → JavaScript → crypto |
| MDN — browser execution timing | HTTP → JavaScript → meta refresh |
Fast facts
- Not a status code — server returns
200, browser navigates after full load. Refresh:HTTP header is the server-injected equivalent (still200).- “Instant” = zero delay after load, not zero elapsed time.
- Mueller’s two “not recommended” reasons: browser history (his reported “afaik”)
- parse-time cost. The Standard itself specifies replace history handling.
- Link equity/PageRank parity with a 301: undocumented either way — don’t assert it.
- Crawlers flag it low-to-medium severity, not critical.
- Use only with no server access (GitHub Pages, Hugo
aliases, static/no-code).
Detecting and reading meta refresh tags
Check one URL from the command line
# Fetch the page and look for the meta refresh tag in the HTML
curl -s https://example.com/old-page/ | grep -i 'http-equiv=["'"'"']*refresh'
# Also check for the server-side Refresh header (case-insensitive)
curl -sI https://example.com/old-page/ | grep -i '^refresh:' A meta-refresh page returns 200 (not a 3xx), so a plain curl -I that only
looks at status codes will miss it — you have to inspect the body and the Refresh
header specifically.
Extract the destination with a regex
The content attribute packs the delay and URL together as N;url=.... This pulls
out both:
curl -s https://example.com/old-page/ \
| grep -io 'content=["'"'"']*[0-9]\+; *url=[^"'"'"'>]*'
# → content="0;url=https://example.com/newlocation"If the leading number is 0 it’s instant (permanent to Google); anything greater
than 0 is delayed (temporary).
XPath (for a rendered DOM or an XML/HTML parser)
//meta[translate(@http-equiv,'REFSH','refsh')='refresh']/@contentThe translate() normalizes the attribute to lowercase so it matches
Refresh, REFRESH, or refresh.
Chrome DevTools console — inspect the current page
// Is there a meta refresh on this page, and where does it point?
const m = document.querySelector('meta[http-equiv="refresh" i]');
console.log(m ? m.getAttribute('content') : 'no meta refresh');Bookmarklet — flag meta refresh on any page you’re viewing
javascript:(()=>{const m=document.querySelector('meta[http-equiv="refresh" i]');alert(m?('Meta refresh: '+m.getAttribute('content')):'No meta refresh tag on this page');})();Save that as a bookmark; clicking it on any page tells you whether a meta refresh is
present and its content value — handy for spot-checking a URL before the refresh
whisks you away.
Two orders, two different questions
Meta refresh appears in two redirect orderings that look contradictory until you name the axis being measured.
| Order | Question | Sequence | What it means |
|---|---|---|---|
| Browser execution | Which mechanism fires first when several exist? | HTTP redirect → JavaScript → meta refresh | Meta refresh waits until the page loads; synchronous JavaScript can run first |
| Google reliability | Which mechanism is Google most likely to interpret correctly? | Server-side 301/308 → instant meta refresh → JavaScript | Parsed HTML is more dependable than a redirect that requires successful JavaScript rendering |
Use the framework in three steps:
- Identify the question. Debugging what the browser did is an execution-order problem. Choosing an SEO migration mechanism is a reliability-order problem.
- Do not convert timing into endorsement. JavaScript firing before meta refresh does not make it Google’s preferred redirect method.
- Choose the strongest available layer. A real server-side permanent redirect remains
the default. If server access is genuinely unavailable, use an instant (
0second) meta refresh with a canonical and visible fallback link, then replace it when server control becomes available.
The same separation explains why an “instant” meta refresh is not network-instant: it adds zero delay only after the document loads, while a server redirect arrives before the document body.
Test yourself: meta refresh redirects
Five quick questions on how meta refresh works and where it fits. Pick an answer for each, then check.
Resources worth your time
My related writing
- 11 Types Of Redirects & Their SEO Impact (Ahrefs, with Joshua Hardwick) — my full redirect ladder, including where meta refresh 0 sits between server-side and JavaScript.
- JavaScript SEO Issues & Best Practices (Ahrefs) — the rendering side, and why JS redirects sit below meta refresh in reliability.
- What is ‘meta refresh redirect’ and why is it considered a critical issue? (Ahrefs Help Center) — the Site Audit framing for the crawl-flag audience (note: its “doesn’t pass link juice” line isn’t backed by Google’s documentation either way — see the Advanced lens for why to avoid the claim in both directions).
My speaking
- How Search Works (SlideShare) — my walkthrough of crawling, rendering, indexing, and ranking, the pipeline a client-side redirect has to survive. (Standing disclaimer: “This is my understanding of systems… not going to be 100% complete or accurate.”)
From around the industry
- Redirects and Google Search (Google Search Central) — the primary source for the instant/delayed split and the preference order.
- Google Says Meta Refresh Redirects Work Fine But Not Recommended (Search Engine Roundtable) — Barry Schwartz relaying Mueller’s “should just work” tweet and his two reasons against it.
- Google Warns Using Meta Refresh May Lead to Wrong Content Getting Indexed (Search Engine Journal) — the “payment page gets indexed instead of your content” failure mode.
- Redirections in HTTP (MDN) — the browser execution order of precedence (distinct from Google’s SEO order).
- Redirects using a Meta refresh (Sitebulb) — the audit-tool workflow for finding and triaging them.
- Internal Redirection (Meta Refresh) (Screaming Frog) — how the crawler flags it, and at what severity.
- Redirect a GitHub Pages site with this HTTP hack (Opensource.com) — a real-world “no server access” meta-refresh example on a static host.
Meta refresh redirect
A meta refresh redirect is a client-side redirect written as an HTML <meta http-equiv="refresh"> tag (or an equivalent HTTP Refresh header) — not an HTTP status code. The server returns a normal 200, then the browser navigates after the page loads. An instant (0-second) one is read by Google as permanent; a delayed one as temporary.
Related: 301 redirect, Redirect
Meta refresh redirect
A meta refresh redirect (also called a “meta refresh,” “HTML refresh,” or “meta refresh tag”) is a client-side redirect written as an HTML <meta> tag in the document <head>:
<meta http-equiv="refresh" content="0;url=https://example.com/newlocation">
It is not an HTTP status code — no 3xx response is ever sent. The server returns a normal 200 OK, and per the HTML Standard’s timing rules the browser only acts on the redirect instruction once the page is treated as completely loaded (and can still cancel or skip it based on user/browser preferences). There’s also a server-injected equivalent, the Refresh HTTP header, which shares the same processing model.
The leading number in content (seconds) splits it into two variants Google treats differently:
- Instant —
content="0;url=...". Fires as soon as the page finishes loading. Google interprets it as a permanent redirect, the same canonicalization signal as a 301/308. - Delayed —
content="5;url=..."(any value greater than 0). Waits N seconds after load. Google interprets it as a temporary redirect, and the delay is the trait most associated with old-school doorway/spam use.
In Google’s documented order of redirect reliability it sits in the middle — below server-side redirects and above JavaScript window.location redirects — because it can’t fire until the whole page loads. It’s a legitimate last resort when you have no server-side redirect access (some static hosts), but a real 301 is the stronger, faster signal whenever you can use one.
Related: 301 redirect, Redirect
Build-time retrieval analysis plus live signals for this exact article. The automatic chunk report includes a deterministic readiness score and is ready without a model download.
Search Console
sampleGA4 traffic (28d)
sampleCloudflare traffic (7d)
sampledCrUX field data (28d, phone)
sampleGoogle NLP entities
localChangelog
Updated Jul 18, 2026.
Editorial summary and recorded change details.Summary
Walked back an unproven PageRank/link-equity-parity claim to what Google actually documents (a canonicalization signal, not identical outcomes to a 301), added HTML Standard detail on the declarative-refresh algorithm (relative URL resolution, first-refresh-wins, javascript: rejection, cancellation/preferences/sandbox), flagged that the current Standard specifies replace history handling against the widely repeated 'keeps the old page in history' framing, softened WCAG technique references (H76/G110/F41) to 'sufficient technique, not mandatory conformance rule,' removed an unsourced 'Bing directionally agrees with Google' claim, and consolidated a meta-refresh source-page audit sequence in the Advanced lens and checklist.
Change details
-
Link equity/PageRank framing (Advanced 'Detecting' section, Anti-Patterns, ai-summary, cheat-sheet) now says Google's classification is about canonicalization interpretation, not a documented promise of identical PageRank/ranking parity with a 301 — corrects an overstated 'same strong signal' claim.
-
Added an HTML Standard subsection to the Advanced lens covering due-time timing, relative URL resolution, first-declarative-refresh-wins, javascript: scheme rejection, and that the navigation can be canceled/adjusted/blocked rather than guaranteed.
-
Flagged that the current HTML Standard specifies replace history handling for the refresh navigation, alongside Mueller's 2018 'keeps the page in browser history, afaik' quote, instead of presenting the history claim as settled fact.
-
Reframed WCAG H76/G110/F41 references as sufficient-technique examples tied to the 2.2.1 Timing Adjustable success criterion, not automatic pass/fail rules.
-
Removed an unsupported claim that Bing 'directionally agrees with Google' on meta refresh treatment; no source establishes Bing's position.
-
Added a consolidated meta-refresh source-page audit sequence (HTTP status/headers, effective refresh directive, canonical/robots/indexability, final response) to the Advanced lens and the checklists lens.
Full comparison unavailable — no prior snapshot was archived for this revision.