# Meta refresh and JavaScript redirects: how Google treats them and when to use one

> A meta refresh redirect or a JavaScript redirect moves visitors after the page has loaded, not on the server. How Google treats each, when they are the only option and how to write one safely.

Updated 2026-09-26 · Technical SEO · HTML version: https://getreport.app/guides/meta-refresh-and-javascript-redirects

A meta refresh redirect is an HTML tag, `<meta http-equiv="refresh" content="0; url=/new-page/">`, that tells the browser to load another address once the page arrives; a JavaScript redirect does the same with a script such as `window.location.replace()`. Both are client-side redirects: the server answers `200 OK` and the move happens afterwards, in the browser. Google follows both, treating an instant meta refresh as permanent, but it recommends them only when a server-side 301 is not possible. This guide explains how each is treated, when one is the right tool, and how to write it so visitors, search engines and link previews all end up in the right place. For server redirects and the status codes behind them, see the [301 redirects guide](https://getreport.app/guides/301-redirects).

## Quick answer

- **Prefer a server redirect.** A 301 or 308 from the server, host or CDN is faster and every client understands it.
- **Meta refresh with 0 seconds** is treated by Google as a permanent redirect. With any delay, Google treats it as temporary.
- **JavaScript redirects** work in Google only after the page is rendered, and Google says to use them only when server-side and meta refresh redirects are not possible.
- **Link previews and most AI crawlers do not run JavaScript,** so they never see a JavaScript redirect.
- **Timed redirects fail accessibility guidance.** A page that moves on its own after a few seconds can strand screen reader and keyboard users.
- **Add a canonical and a plain link** on the redirecting page as a backup.

## Server-side vs client-side redirects

A server-side redirect answers the request itself with a 3xx status code and a `Location` header. The browser never receives a page; it goes straight to the new address. Search engines, link-preview bots, `curl` and every HTTP client understand it without running any code.

A client-side redirect is a normal page that answers `200 OK`. The browser downloads the HTML, reads the meta tag or runs the script, and only then requests the new address. That has three costs:

1. **Speed.** The visitor waits for the first page to arrive, and for a JavaScript redirect often for scripts to load, before the second request even starts.
2. **Reach.** Only clients that read the HTML, or run JavaScript, follow it. Everything else stays on the old page.
3. **Clarity.** Tools and crawlers that look at status codes see a working page, not a moved one.

Google's documentation on redirects ranks the options. For permanent moves it lists the HTTP 301 and 308 status codes first, then an instant meta refresh or an instant HTTP `Refresh` header, then JavaScript. For temporary moves it lists 302, 303 and 307, and a delayed meta refresh.

## How Google treats a meta refresh redirect

The tag goes in the `<head>` of the old page:

```html
<!-- /old-page/index.html -->
<meta http-equiv="refresh" content="0; url=https://example.com/new-page/">
```

The number is the delay in seconds, then `url=` and the target. Google reads it without rendering the page, because it is part of the HTML, and treats it by the delay:

| Delay | Google treats it as | Use it for |
| --- | --- | --- |
| `0` | Permanent redirect, like a 301 | A page that has moved for good, when you cannot set a server redirect |
| `1` or more | Temporary redirect, like a 302 | Rarely anything; the old URL stays the indexed one |

A delayed meta refresh is also the old "you will be redirected in 5 seconds" page. Beyond the SEO signal, it fails accessibility guidance: WCAG's failure technique F40 describes a timed meta redirect as a failure of the Timing Adjustable criterion, because people who read slowly or use a screen reader can be moved away mid-sentence without control. An instant redirect, with a delay of 0, is the accessible form (WCAG technique H76).

The same instruction can be sent as an HTTP header, `Refresh: 0; url=https://example.com/new-page/`. Browsers honour it and Google treats an instant one like an instant meta refresh, but the server is then already involved, so a real 301 is almost always possible instead.

## How Google treats a JavaScript redirect

A JavaScript redirect changes `window.location` once the script runs:

```html
<script>
  // replace() does not leave the old page in the back-button history
  window.location.replace('https://example.com/new-page/');
</script>
```

Use `location.replace()` rather than setting `location.href`. With `href`, the old page stays in the history, so the back button returns to it and the script sends the visitor forward again, which feels like a broken back button.

Google processes JavaScript redirects when it renders the page, which happens after crawling and can take longer. Google's redirect documentation says to use them only if you cannot do server-side or meta refresh redirects. In practice Google follows a simple, unconditional `location.replace()` reliably. It is the conditional cases that go wrong: redirects that depend on a cookie, a click, the screen size, the browser language or a timer can behave differently for Googlebot than for visitors, or not fire at all.

Crawlers that do not render JavaScript never follow it. That includes most link-preview bots for chat apps and social networks, so a shared old URL shows the old page's title and image, and many AI crawlers, which read the raw HTML without running scripts. The [JavaScript SEO guide](https://getreport.app/guides/javascript-seo) explains rendering and what reaches Google without it.

### JavaScript redirects in single-page apps

Frameworks such as React, Vue and Angular redirect inside the app with their router. Those are JavaScript redirects too. For URLs that have really moved, add the redirect at the host instead, such as Netlify `_redirects` or Vercel's `redirects` in `vercel.json`, so it answers with a 301 before the app loads; the [static sites guide](https://getreport.app/guides/netlify-and-vercel-headers-and-caching) covers where those files live.

A router is also where soft 404s come from: a missing product renders "Not found" with a `200` status. Google's JavaScript SEO documentation suggests either a JavaScript redirect to a URL where the server answers 404, or adding `noindex` to the error view. The [soft 404 guide](https://getreport.app/guides/soft-404s-what-they-are-and-how-to-fix-them) has the details.

## When a client-side redirect is the right choice

Use a meta refresh or JavaScript redirect only when a server-side redirect is not available:

- **Static hosting without redirect rules,** such as some static site hosts. Generators such as Jekyll's `jekyll-redirect-from` plugin create exactly this kind of page.
- **Hosted platforms** that let you edit a page's HTML but not the server response.
- **A file you do not control the server for,** such as a page on shared storage.
- **A soft-404 fix in a single-page app,** as described above.

If your platform has any redirect feature, even a basic one, use it instead. WordPress, Shopify, Webflow, Wix and Squarespace all have one, as do Netlify, Vercel, Cloudflare Pages and most CDNs; for WordPress, see [redirects with a plugin or a server rule](https://getreport.app/guides/wordpress-redirects), and for moving a whole domain, [how to redirect a domain to another domain](https://getreport.app/guides/redirect-domain-to-another-domain).

## How to write a client-side redirect page that works

If a client-side redirect is your only option, make the old page carry every signal it can, so each kind of visitor lands in the right place:

```html
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Moved to /new-page/</title>
  <link rel="canonical" href="https://example.com/new-page/">
  <meta http-equiv="refresh" content="0; url=https://example.com/new-page/">
  <script>window.location.replace('https://example.com/new-page/');</script>
</head>
<body>
  <p>This page has moved to <a href="https://example.com/new-page/">example.com/new-page/</a>.</p>
</body>
</html>
```

- **The canonical tag** tells search engines which URL to index even if they do not follow the redirect.
- **The meta refresh with 0** covers every client that reads HTML, without JavaScript.
- **The script** covers browsers where a meta refresh is turned off, and does no harm elsewhere.
- **The link in the body** is for anyone the other three miss. Keep it; it is the accessible fallback.

Use absolute URLs, keep the page tiny so it loads fast, and point it at the final address, not at another redirect. Update your own links, sitemap and canonicals to the new URL so only outside links ever reach the old page.

### Never redirect to an address taken from the URL

A script such as `location.replace(new URLSearchParams(location.search).get('next'))` lets anyone build a link on your domain that sends visitors to a site of their choosing. Attackers use such open redirects for phishing. Redirect only to fixed addresses or to a list you control.

## How to check a meta refresh or JavaScript redirect

A redirect checker that reads HTTP status codes shows a client-side redirect as what it is to a crawler: a page that answers `200`.

> **Free tool:** [Redirect checker: 301, 302 and redirect chains](https://getreport.app/tools/redirect-checker): Free redirect checker: follow every hop from your URL to the final page, with status codes, HTTP to HTTPS and www redirects, and the canonical at the end.

Enter the old URL. If it ends on the old address with a 200, no server redirect exists, and any move you see in the browser is happening in the page. That is your cue to replace it with a server rule wherever the platform allows; the [redirect rule generator](https://getreport.app/tools/redirect-generator) writes those rules for Apache, nginx, Cloudflare, Netlify, Vercel and Caddy from a list of old and new URLs.

To confirm what Google makes of a client-side redirect, use URL Inspection in Search Console on the old URL and check which URL Google selected as canonical. Look at the page source, not the rendered page, to see whether the meta tag is really there.

### Redirects you did not add

JavaScript redirects are also a favourite of hacked sites: injected scripts that send visitors from Google, or Googlebot itself, to a spam site, while you see the normal page when you visit directly. The full getReport report checks for it:

> **Check: No redirect that fires only for Googlebot or Google visitors.** The page sends visitors who come from Google, or Googlebot itself, to another site, while direct visitors see the normal page. Owners rarely notice because they never arrive from Google. Search results show the spam target and the site loses its rankings.
>
> 1. Look for the redirect in .htaccess or the nginx config, in wp-config.php and index.php, in theme header and footer files, in the database (wp_options siteurl/home and injected scripts in posts), and in inline scripts that read document.referrer.
> 2. Remove it, update and clean the site, rotate passwords, and request a review in Search Console.

If it fails, follow the [hacked WordPress recovery guide](https://getreport.app/guides/recovering-a-hacked-wordpress-site-step-by-step) or the [hacked site fix page](https://getreport.app/learn/hacked-site).

## Common mistakes

- **A client-side redirect where a server rule was possible.** It is slower for every visitor and invisible to many clients.
- **"You will be redirected in 5 seconds" pages.** Temporary to Google and an accessibility failure.
- **`location.href` instead of `location.replace()`.** The back button bounces visitors forward again.
- **Redirecting based on language or country in JavaScript.** Googlebot may never see the other versions. Link them with hreflang instead.
- **A redirect page with no canonical and no link.** Crawlers that ignore the redirect index the empty page.
- **Chains through client-side redirects.** A meta refresh to a page that 301s again multiplies the delay.

## Questions people ask

### Is a meta refresh redirect bad for SEO?

Not when the delay is 0. Google treats an instant meta refresh as a permanent redirect, much like a 301, so the new URL replaces the old one. A delayed refresh is treated as temporary, keeps the old URL indexed and fails accessibility guidance. Use a server-side 301 when you can; it is faster and every client follows it.

### Does Google follow JavaScript redirects?

Yes, when it renders the page, which can take longer than crawling. Google follows a simple, unconditional redirect such as `window.location.replace()`, but recommends JavaScript redirects only when server-side and meta refresh redirects are impossible. Link-preview bots and most AI crawlers do not run JavaScript, so they never follow them.

### What is the difference between a meta refresh and a 301 redirect?

A 301 is the server's answer to the request: status code 301 and the new address, with no page at all. A meta refresh is a tag inside a normal page that answers 200, so the browser must download and read the HTML before it moves. Google treats an instant meta refresh like a 301, but the 301 is faster and understood by every client.

### How do I redirect with JavaScript without breaking the back button?

Use `window.location.replace('https://example.com/new-page/')` instead of setting `window.location.href`. `replace()` swaps the current history entry, so pressing back goes to the page before the redirect. With `href`, back returns to the redirecting page, which sends the visitor forward again, and they appear to be stuck.
