# Pages that reload or redirect themselves on a timer

Source: https://easeweb.dev/learn/meta-refresh
Topics: Time limits and motion > Pages do not reload or redirect on a timer (WCAG 2.2.1)
The fix: Delete the meta refresh and end the page with a Continue shopping link, so it stays until people choose to leave. A script timer or a Refresh header that moves the page on fails in the same way, so swapping the meta element for either is not a fix; a page that has moved is redirected on the server at once instead.
Test with: keyboard, screen reader, zoom
References: https://www.w3.org/WAI/WCAG22/Understanding/timing-adjustable.html https://www.w3.org/WAI/WCAG22/Techniques/failures/F40 https://www.w3.org/WAI/WCAG22/Techniques/failures/F41 https://www.w3.org/WAI/WCAG22/Techniques/failures/F58 https://html.spec.whatwg.org/multipage/semantics.html#attr-meta-http-equiv-refresh https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Refresh https://dequeuniversity.com/rules/axe/4.10/meta-refresh

This is a recreated teaching example, not a finding about a named client. The code is a starting pattern: test it in your own product. No completed assistive-technology test is claimed here.

## What happens

A stationery shop's checkout ends on a confirmation page: "Thank you for your order. Your order number is 4821. Your parcel will arrive on Friday 23 October." The last line says "You will be taken back to the shop in 10 seconds", and ten seconds later the browser goes to the shop's home page by itself. A line in the page's head does it, so that nobody is left on a dead end.

Ten seconds is enough for someone who glances at the page and is happy. A screen reader user hears the page title and the heading, and the home page may start being read before the reading reaches the order number: they are moved on without the number or the delivery date. Someone zoomed in with a magnifier is still finding the number. Someone copying it with a head pointer is halfway through selecting it. Nothing on the page stops the timer or gives more time.

## Why it fails

Success Criterion 2.2.1 Timing Adjustable covers every time limit that content sets, and a page that moves itself on after a delay is one: whatever people want from the page, they have to get before the timer ends. For each limit, people must be able to turn it off, adjust it to at least ten times the default, or be warned and given at least 20 seconds to extend it with a simple action, at least ten times. A limit longer than 20 hours, a real-time event such as an auction, and a limit essential to the activity are exempt. A confirmation page meets none of these. "You will be taken back to the shop in 10 seconds" warns people, but gives them nothing to extend it with.

W3C names the ways such a timer is built as failures of 2.2.1. F40 is a meta refresh that redirects to another page after a delay, like this one, and F41 is a meta refresh that reloads the same page, such as a live score page that reloads every minute. F58 is the same instruction sent by the server as a `Refresh` HTTP header, which browsers follow just as they follow the meta element. A script that sets `location.href` from a timer has the same effect as the redirect F40 describes. A meta refresh with a delay of 0 passes, because it redirects at once, before anyone has started reading.

## Who is affected

The people who need the confirmation most are the ones the timer cuts off. An email receipt may come later, but the page was where they meant to read the number and the delivery date, and the shop sent them away from it.

## What automation and AI miss

axe's `meta-refresh` reports a meta refresh with a delay of more than 0 and no more than 20 hours, which finds this page. It can't see the other two forms. A `Refresh` header is not in the page, so the audit reads the response's headers and reports it as `ew:refresh-header`. A script timer only shows when it fires, and a scan that loads the page and leaves can be gone before it does, so the audit watches the timers a page starts by itself and sends any that would reload it or leave it to review (`ew:timed-reload-manual-check`), since only a person can tell whether it really moves the page on. AI assistants asked for a thank-you page that "returns people to the shop" can write the meta element, or `setTimeout(() => { location.href = '/'; }, 10000)` when told the meta element fails, which silences the scanner and keeps the failure.

## Before: a confirmation page that leaves after 10 seconds

```html
<head>
  <title>Order placed – Northfold</title>
  <meta http-equiv="refresh" content="10; url=/">
</head>
<body>
  <main>
    <h1>Thank you for your order</h1>
    <p>Your order number is 4821.</p>
    <p>Your parcel will arrive on Friday 23 October.</p>
    <p>You will be taken back to the shop in 10 seconds.</p>
  </main>
</body>
```

The browser goes to the home page 10 seconds after the confirmation opens, whatever the person is doing. The page says so, but nothing lets anyone turn it off or ask for more time.

## After: a link that goes back when people are ready

```html
<head>
  <title>Order placed – Northfold</title>
</head>
<body>
  <main>
    <h1>Thank you for your order</h1>
    <p>Your order number is 4821.</p>
    <p>Your parcel will arrive on Friday 23 October.</p>
    <p>
      <a href="/">Continue shopping</a>
    </p>
  </main>
</body>
```

With the meta element gone, the page stays until people choose to leave, and the link takes them to the shop when they are ready. Nobody is left on a dead end, which is what the timer was for. This is the smallest change: one line deleted, and the last sentence turned into a link.

## Implementation decisions

**Pages that reload on a timer.** A live score, a departures board or an order-tracking page with `<meta http-equiv="refresh" content="60">` reloads itself every minute, and a screen reader starts again from the top each time. Give people a link or button that loads the new content when they choose. If the page has to keep itself up to date, fetch only the part that changes and write it in place, with a Pause button before it, since content that updates by itself beside other content also falls under 2.2.2 Pause, Stop, Hide.

**Pages that have moved.** "This page has moved. You will be taken to the new one in 5 seconds" fails the same way. Redirect on the server with a 301 or 308 status instead, which happens before anything is shown.

**The Refresh header.** `Refresh: 10; url=/` in a response is the meta element sent from the server, set in a framework's response helper or a web server's configuration. Remove it in the same way, and check the headers in the browser's network panel, since nothing in the page source shows it.

**A countdown is not a way out.** Showing the seconds as they count down, or saying how long is left, tells people the page will move, but still leaves them no way to stop it. Remove the timer rather than decorate it.

**Sessions.** A page that signs people out after a time, or sends them to a "session expired" page, is a time limit with its own guide: [session timeouts with no warning or way to extend](/learn/time-limits). At AAA, 3.2.5 Change on Request goes further and asks that changes of context happen only when people ask, or can be turned off; that is a topic of its own.

## Verify the fix

1. Search the templates for `http-equiv="refresh"`, read the response headers of each page type in the network panel for `Refresh`, and search the scripts for `location.reload`, `location.assign`, `location.replace` and assignments to `location` inside `setTimeout` or `setInterval`. None reloads or redirects the page on a timer.
2. Open the confirmation page and leave it alone for at least a minute: it stays, and the address doesn't change.
3. With a screen reader, read the page from the top at your usual speed: you reach the order number and the end of the page.
4. Using only the keyboard, Tab to Continue shopping and press Enter: it takes you to the shop.
5. With a screen magnifier zoomed in, pan across the whole page at your own pace: nothing moves on until you choose.

Record the OS, browser and assistive-technology versions, the build, the date, and the actual result of each step. Repeat after the page templates, the checkout or the server's headers change.

## Limits

This covers pages that reload or redirect themselves after a delay. Content that moves or scrolls by itself has its own guide, [tickers, carousels and animations that can't be paused](/learn/moving-content), and a session that signs people out is covered in [session timeouts with no warning or way to extend](/learn/time-limits). A payment or booking page from another provider, shown before your confirmation, is part of the same checkout: check it for a timed return as well. Screen readers differ in what they read when a page loads: test with the ones your users have.

---

Get this guide in your coding agent: MCP https://easeweb.dev/mcp (setup at https://easeweb.dev/services/developers)
