meta http-equiv=refresh: redirects and auto-refresh
A timed redirect moves the page out from under a screen reader user mid-sentence. squirrel reads the content value and grades it.
What meta refresh is
<meta http-equiv="refresh" content="5;url=/new"> asks the browser to load another page after a delay. With no url it reloads the current page on a timer instead.
Both take control away from the reader. Someone using a screen reader, or reading slowly, or filling in a form, gets moved without warning and with no way to stop it. WCAG success criterion 2.2.1 Timing Adjustable, Level A, covers time limits like this, and techniques F40 and F41 name meta refresh specifically as a way to fail it.
What squirrel checks
One check name per case, at rule severity error. The rule finds the first <meta> whose http-equiv is refresh, matched case-insensitively, and parses its content as a number of seconds optionally followed by ;url=.
meta-refresh-redirectwarns withImmediate meta refresh redirect foundwhen a url is present and the delay is zero, carrying the issueUse server-side 301/302 redirect instead.meta-refresh-redirectfails withMeta refresh redirect after N secondswhen a url is present and the delay is anything other than zero, which includes a negative or unparsable value, carrying the issueTimed redirects disorient users.meta-refresh-autofails withPage auto-refreshes every N secondswhen there is no url and the delay parses to a number above zero and under 20, carrying the issueFrequent refresh disrupts screen reader users.meta-refresh-autowarns withPage auto-refreshes every N secondswhen there is no url and the delay is 20 seconds or more, suggestingProvide user control over refresh.meta-refreshpasses withNo meta refresh found.
Every finding carries the raw content string as its value. The 20 second boundary is squirrel’s own, not a threshold from the standard.
Two gaps are worth knowing. Only the first matching <meta> is examined, and a content="0" with no url matches none of the branches, so it produces no finding at all.
Elements inside <noscript> are skipped: a browser with scripting enabled reads <noscript> content as plain text, so nothing in it loads or renders. See content inside noscript.
How to fix it
For a redirect, do it on the server:
HTTP/1.1 301 Moved Permanently
Location: https://example.com/new
A 301 or 302 never renders the old page, so nothing is read out and then replaced. It is also the version search engines follow cleanly.
For content that has to stay current, fetch and update the region in place with aria-live="polite" rather than reloading the document, and give the user a control to pause it.
| Rule ID | a11y/meta-refresh |
| Category | Accessibility |
| Scope | Per-page |
| Severity | error |
| Weight | 7/10 |
Enable / disable
Disable this rule
[rules]
disable = ["a11y/meta-refresh"]Disable all Accessibility rules
[rules]
disable = ["a11y/*"]Enable only this rule
[rules]
enable = ["a11y/meta-refresh"]enable replaces the default ["*"], so this is the only rule selected. Leave disable out: a rule that matches any disable pattern is skipped even when enable names it. Only an enabled setting under a rule’s own [rule_options] table overrides both lists.
Related rules
- links/redirect-chains: URLs that redirect and links pointing at them, once the redirect moves to the server.
- a11y/zoom-disabled: another meta tag that takes control away from the user.
- core/robots-meta: the other directives that live in the same
<head>. - a11y/skip-link: whether the page offers any way past its repeated navigation.
Accessibility findings ship in every audit next to the SEO, performance and agent experience rules. See Website security scan with AI for how an agent works through a report.
References
- F40: Failure due to using meta redirect with a time limit, W3C
- F41: Failure due to using meta refresh to reload the page, W3C
- meta http-equiv=refresh, HTML Standard
Check your site
Run squirrel audit https://example.com and open the Accessibility section of the report. The finding quotes the raw content value so you can see the delay and the target. Signed-out local audits need no account and cost nothing. Signed-in audits spend credits.