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.

First published: Jun 28, 2026 · Last updated: Jul 18, 2026 · Advanced
demand #5 in Redirects#16 in HTTP Status Codes#132 in Technical SEO#181 on the site

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 is an HTML <meta http-equiv="refresh"> tag (or the server-injected Refresh header), not a 3xx status code — the server returns 200 and 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 redirectsA JavaScript redirect is a client-side redirect that uses code like window.location.replace() to send a visitor (and crawler) to a different URL. Because it only fires after the page is downloaded and rendered, Google prefers server-side and meta refresh redirects above it. 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, prefer 0, pair it with rel=canonical and a visible fallback link, and replace it with a real 301 as soon as you can.

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

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/newlocation

Note that even the header version returns 200, not a 3xx. Either way, this is a client-side redirectA redirect sends browsers and crawlers from a requested URL to a different one. An HTTP redirect specifically is a 3xx status code paired with a Location header; meta refresh and JavaScript redirects achieve a similar navigation without being a 3xx response themselves. Permanent redirects (301/308) are Google's signal the target should be canonical; temporary ones (302/303/307) aren't.: 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 instant meta refresh redirects as permanent redirectsA 301 redirect is the HTTP status code for a permanent move: it tells browsers and search engines a URL has moved for good, and it's the strongest signal for consolidating a page's ranking signals onto the new URL. Google says permanent redirects don't cause a loss in PageRank..” So for canonicalizationHow search engines pick one canonical URL among duplicates and consolidate signals onto it. 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 (content greater than 0) — “Triggers only after an arbitrary number of seconds… Google Search interprets delayed meta refresh redirects as temporary redirectsA 302 (\"Found\") is a temporary redirect: it forwards users to a new URL while telling search engines the original URL should stay in the index. It's a weak canonicalization signal, not the zero-equity dead end of SEO folklore..” Like a 302/303/307, the target might still be indexedStoring a crawled page in the search index so it can appear in results. Crawled is not the same as indexed — Google selects what to keep, and indexing isn't guaranteed. 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 301HTTP 308meta 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 hubA redirect sends browsers and crawlers from a requested URL to a different one. An HTTP redirect specifically is a 3xx status code paired with a Location header; meta refresh and JavaScript redirects achieve a similar navigation without being a 3xx response themselves. Permanent redirects (301/308) are Google's signal the target should be canonical; temporary ones (302/303/307) aren't., which notes that JS and delayed meta-refresh are weaker because they depend on renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM..

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 renderingTurning HTML, CSS, and JavaScript into the final visual page and DOM. 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 resourcesRender-blocking resources are CSS and synchronous JavaScript files a browser must download and process before it can paint any visible content. They sit on the critical rendering path and delay First Contentful Paint and Largest Contentful Paint.) 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 a Refresh header) 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 the javascript: 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-agentA user agent is the HTTP request header a client (browser, crawler, or bot) sends to identify itself. For crawlers, a short user-agent token — a substring of that string — is what robots.txt rules actually target. 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.

Accessibility: 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 SEOHugo SEO is the practice of optimizing sites built with Hugo, the Go-based static site generator. Hugo outputs finished HTML at build time, so content is in the raw HTML on the first fetch — but that alone doesn't guarantee good Core Web Vitals or rankings, and canonicals, taxonomy duplication, and aliases-vs-301s still need hands-on configuration..)
  • 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 canonicalizationHow search engines pick one canonical URL among duplicates and consolidate signals onto it. 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 chainA → B → C instead of A → C. Each hop loses link equity and adds latency. — 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

CrawlersA crawler — also called a spider or bot — is an automated program that fetches web pages, extracts their links, and queues new URLs to visit. Search engines use crawlers to discover and download content for their index. 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 PageRankPageRank is Google's original recursive link-graph algorithm: a page's score depends on the scores of the pages linking to it, and in the published model each page's score is split across its outbound links (the simplified version: links are weighted votes). Google says it's evolved since launch but still part of its core ranking systems., 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 tagA rel=\"canonical\" annotation — in the HTML <head> or an HTTP Link header — that tells search engines which URL is the preferred version of duplicate or near-duplicate content., 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 linksAn internal link is a hyperlink from one page on a website to another page on the same website. Internal links help search engines discover your pages and pass ranking signals (PageRank and anchor-text context) between them. 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.

TIP Expose a meta refresh inside an otherwise successful response

The source and destination can both return 200 while the browser still performs a client-side transition. Replace it with one server-side redirect when you control the response.

Trace the transition with my free Redirect Checker Free

  1. Test the source URL and inspect the full transition rather than its final page alone.
  2. Replace the meta refresh with a direct server-side 301 or 308 when the move is permanent.
  3. Rerun the trace and confirm the source returns the intended redirect without a client-side hop.
A 200-to-200 trace can still contain a redirect-like browser instruction that depends on loading the source HTML.

The result labels the trace a long chain and fix recommended. It shows a meta-refresh transition from example.com old to example.com final, both with 200 responses, and recommends replacing the client-side hop with a server-side 301 where possible.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.