SEO QA · Verification process
Pre-deployment SEO testing checks a release candidate on a staging or preview environment and compares it with what production serves today. Its output is a decision, not a report: either the build is approved, or a named defect blocks it.
Definition
The baseline is production, because production is what search engines have already crawled. The candidate is the staging build. Every SEO-relevant difference between the two must be explained by a ticket before the build is approved. Anything unexplained is treated as a defect until proven otherwise.
Crawling a protected staging environment
Staging is usually hidden behind protection, so the crawl has to be configured to get in without treating the protection as a finding.
| Protection | How to crawl it | What to ignore in results |
|---|---|---|
| HTTP basic auth | Add credentials in crawl settings | 401 on assets served from other hosts |
| IP allowlist | Run the crawler from an allowlisted machine or VPN | Nothing, if allowlisting works |
| Preview URLs per pull request | Crawl the preview host for the branch | Hostname differences, after normalizing |
| Staging-wide noindex | Crawl normally | noindex, but only if it comes from environment config |
Use the same URL limit, start URL, user agent and rendering mode as the production baseline. Changed settings produce differences that have nothing to do with the release.
Proving blocks are environment-driven
A staging noindex is fine. A noindex hardcoded into a template, which happens to be correct on staging, will ship to production. The test is to find out where each block comes from.
| Signal | Safe source | Unsafe source | How to tell |
|---|---|---|---|
| Meta robots noindex | Template reads an environment flag | Literal noindex in template or CMS setting | Search the build output and template code for the literal value |
| X-Robots-Tag | Staging server or CDN config only | Application middleware shipped with the build | Compare middleware files between branches |
| robots.txt Disallow: / | Generated per environment | Static file committed to the repository | Check whether robots.txt is a file in the build |
| Canonical host | Base URL variable set per environment | Hostname written into templates | Staging canonicals use the staging host, and the variable exists in production config |
Set the environment flag to production on a single staging instance and crawl five URLs. If noindex or Disallow remains, the block is not environment-driven.
Comparing staging to the production baseline
Normalizing hostnames means treating staging.example.com and www.example.com as the same site so that /pricing/ on one lines up with /pricing/ on the other. Audit comparison then lists the differences per URL. Requirements for each change should already exist as SEO acceptance criteria on the ticket.
Before and after example
200 · index, follow
canonical: www.example.com/products/sofa-grey/
200 · index, follow
canonical: staging.example.com/products/sofa-grey/
Go or no-go matrix
| Severity | Example | Decision |
|---|---|---|
| Blocker | Indexable template gains noindex, canonical to wrong host, template returns 404 | No-go |
| Major | H1 removed from a template, structured data invalid | Go only with the fix in the same sprint |
| Minor | Description length changes on a few URLs | Go |
| Expected | Change listed in the ticket | Go, note for post-release comparison |
Record the decision with the staging crawl attached. After release, the same build is verified on the live site in post-deployment SEO testing.