Should a Shopify store run accessibility scans on staging, production, or both?
Run accessibility scans on staging for every release and on production on a schedule. Staging tells you what the next deploy will break; production tells you what is already broken for real users.
What staging scans catch
Staging scans are a release gate: they answer whether the next deploy introduces new accessibility issues. Run the scan against the staging build before every production push, diff it against the last clean production scan, and block or flag on new findings. This is where automated scanning earns its keep, because it turns accessibility from a periodic project into a property of every release. The team learns that breaking accessibility breaks the build, and behavior changes fast.
Staging is also the only safe place to scan aggressively. Full-page crawls, authenticated flows, checkout-adjacent paths, and heavy interaction scripts can all run on staging without touching real customers or polluting analytics. You can scan every template, every product type, every edge case the theme supports. On production, that same thoroughness looks like a bot attack to your own monitoring. Staging is where you scan deep.
The trap with staging-only scanning is the assumption that staging equals production. It rarely does. Content differs, third-party scripts load differently, personalization and A/B tests render different variants, and the apps installed on production are not always mirrored on staging. A clean staging scan is evidence about the staging build. Treat it as a gate, not a guarantee.
What only production reveals
Production scans catch everything staging hides: the app that only loads for real customers, the cookie consent banner that behaves differently under real geolocation, the checkout extensions that only render on live traffic, the marketing team's landing pages that were never in the theme at all. On Shopify especially, a large share of accessibility risk lives in layers that staging never sees: apps, scripts, and content added outside the deploy pipeline.
Production also reveals the issues that only exist at scale: the search results page with real inventory, the collection page with two hundred products, the cart drawer under a heavy discount code. Staging usually has sample data. Production has the real catalog, and the real catalog breaks things in ways sample data does not. Scan the pages real customers actually visit, weighted by traffic, and you find the issues that affect real people.
Schedule production scans, do not gate on them. A weekly or biweekly full scan of production, compared against the previous run, shows drift: the new app someone installed, the theme tweak that shipped outside the process, the content change that broke a heading structure. Production scanning is a monitoring function. Its output is a trend, not a verdict.
How to schedule both without doubling the noise
The noise problem is real: two scan sources can mean two alert streams, duplicate findings, and a team that trusts neither. The fix is one findings ledger with the source attached. A finding is a finding; the scan that surfaced it is metadata. When staging and production both flag the same missing label, the ledger shows one issue found in two places, not two issues. Dedupe on the finding, not the scan.
Give each source its own job in the workflow. Staging findings go to the developer who owns the release, as part of the deploy checklist. Production findings go to the accessibility owner as drift to triage, on the weekly review. Different readers, different cadences, one ledger. The staging gate stays strict because it is about new issues; the production review stays calm because it is about trends.
One more rule: scan production after every staging-gated release, once. The post-release production scan is the reconciliation: did what we shipped match what we scanned? This closes the loop between the two sources and catches the cases where staging and production genuinely differ. It takes one scheduled scan and it is the highest-value scan in the whole program.