Search topics
Pages that reload or redirect themselves on a timer
An order confirmation page carries a meta refresh that sends people back to the shop 10 seconds after it opens, whether or not they have read their order number.
<meta http-equiv="refresh" content="10; url=/"> The problem
Screen reader users, magnifier users and people who read slowly are moved off the order confirmation before they have read the order number.
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.
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.
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.
4 of 10 groups affected
- No vision (affected)
- Low vision (affected)
- Colour vision (not affected)
- No hearing (not affected)
- Hard of hearing (not affected)
- No speech (not affected)
- Motor (affected)
- Reach, strength (not affected)
- Cognitive (affected)
- Seizures (not affected)
- Without vision A screen reader reads the page from the top, and ten seconds may not reach the order number before the shop's home page starts being read instead.
- Limited vision Screen magnifier users see a part of the page at a time and need longer to find the order number than the page allows.
- Limited language, cognitive and learning abilities People who read slowly, or read twice to be sure, lose the page before they have taken in the order number and the delivery date.
- Limited manipulation Selecting and copying the order number with a switch or a head pointer can take longer than ten seconds, so the page moves on in the middle of it.
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.
Try it
Place the order, then try to read the confirmation and note the order number before the page moves on.
The confirmation sends you back to the shop 10 seconds after it opens, in real time, whatever you are doing. Then look at what a screen reader would be reading.
Broken Can you fix this?
Check your order
1 × Dot-grid notebook, £14
Delivery: Friday 23 October
Screen reader says:
(Place the order)
The fix
Let people leave the page with a link when they are ready, and redirect a moved page on the server at once.
- 1Never reload or redirect a page on a timer, whether by meta refresh, a Refresh header or a script.
- 2End a confirmation page with a link to where people go next.
- 3Redirect a moved page on the server at once, before anything is shown.
<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><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>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.
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.
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. 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.
Fixing this with an AI coding assistant? Get this guide as Markdown, or get every guide in your coding agent.
Verify the fix
5 checks, no mouse.
Test with: Keyboard, Screen reader, Zoom
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, and a session that signs people out is covered in session timeouts with no warning or way to extend. 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.
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.
References
- WCAG Understanding: timing-adjustable (opens in a new tab)
- WCAG Technique F40 (opens in a new tab)
- WCAG Technique F41 (opens in a new tab)
- WCAG Technique F58 (opens in a new tab)
- html.spec.whatwg.org: semantics (opens in a new tab)
- developer.mozilla.org: Refresh (opens in a new tab)
- dequeuniversity.com: meta-refresh (opens in a new tab)
Keep this fixed as your code changes.
Turn guides like this into rules your coding agents and CI follow, then have the result retested with a keyboard and screen readers.