bpmore/statamic-a11y-gate
An accessibility gate for Statamic that checks content against configurable a11y rules before publishing, helping editors catch issues early and keep sites WCAG-friendly.
This is a Statamic addon that checks an entry's rendered page for accessibility problems and refuses the save when it finds them. Findings are pointers into your own page content — a duplicate heading's text, an image's src, a link's words — so the workflow is "write, press Check, fix what it names, publish".
Minimal steps:
composer require the addon (the README's new ## Installing section has the exact line), on the Statamic and PHP floors it states. Install ext-intl if you want what the README says it adds.php artisan statamic:install, or php artisan vendor:publish --tag=statamic-a11y-gate --force if you only want this addon's files. Read the published config first — that is where you decide which collections are gated.First real use case: take one existing entry that you know has problems, press Check, and read the findings against the page. That tells you faster than the docs whether the gate is scoped correctly for your site.
Check before Save & Publish, not after. The gate hooks the save pipeline, so a refused save is the normal failure mode. Treat a refusal as a normal authoring step: the panel opens with the findings listed, the author fixes the named elements, saves again. On viewports where Statamic folds the sidebar into a tab (tablets, small laptops) the panel now asks Statamic's own reveal to switch to the offending tab and scroll it into view — so the "The given data was invalid" toast is a pointer to the panel, not the whole message. That reveal call is guarded, so a Statamic build without it falls back to drawing the alert in place.
Scope the gate deliberately. The panel is auto-placed on gated collections; keep the gate on the collections that are public-facing and content-heavy, and leave it off internal/utility collections where a refusal is just friction. For collections outside the automatic placement, add the field to the blueprint by hand. The field stores nothing — it is a UI surface only, so do not build queries, exports, or filters against its value.
Findings are untrusted display data, always. As of 0.10.2 every string the panel draws goes through Vue's escaping, page-derived or not. If you write your own panel components, or a custom report view, that renders findings, use {{ }} / v-text — never v-html. The heading that broke this was <img src=/x.png onerror=...> written into page content: escaped and harmless on the front end, decoded and executed in the CP of whoever pressed Check. Assume anyone who can write into a gated entry can put anything in a finding.
Pair it with a real audit for the gaps. The Tools page now says "Anything it finds" rather than "Anything that would fail WCAG 2.2 AA stops the publish" — that is the honest reading. Colour contrast is explicitly not checked. Use the addon as a publish-time tripwire for structural problems, and keep an actual audit (manual or an external scanner) for conformance claims. Do not let a stakeholder read the gate as a compliance guarantee.
Asset publishing is part of your deploy. The panel is Vue components shipped as published assets. If your deploy does not run vendor:publish, the fix in 0.10.2 never reaches the browser. Wire php artisan vendor:publish --tag=statamic-a11y-gate --force into the deploy (or statamic:install) and confirm the published files change when the package version does.
innerHTML, so an author on a gated entry can plant script that runs in an admin's control panel. Upgrading composer.json alone is not enough — the compiled JS in your public/ tree must be refreshed. This was confirmed on a live CP, not reasoned from the code.--tag=laravel-assets is wrong. The 0.8.0 release note told you to use it, and it publishes nothing for this addon. The correct tag is statamic-a11y-gate. Any blog post, bookmark, or internal runbook copied from that note is still wrong.list-disc, it was silently dropped, and lists drew flat for several releases. 0.10.2 now uses an inline style and ships a test that reads the build and checks every class the addon writes against it. If you extend the panel with your own markup, do not assume a utility class is present — check the built stylesheet, or use inline styles for anything structural... (Laravel's own message supplies the full stop, and each quote was adding another), and the Tools page copy changed to "Anything it finds". If you assert on those strings in tests or screenshot them in docs, update both.listable: false as of 0.10.2 — the field stores nothing, so the column could only ever be empty. If someone asks for "accessibility status at a glance in the entries list", that is a custom build, not a config toggle.composer.json support key and the README's ## Support section point at the same place. Plan for that if you are putting this in front of a large authoring team — the answers are in the tracker and the README, not in a private channel.How can I help you explore Laravel packages today?