Most SEO disasters aren't caused by bad strategy. They're caused by a release.
A new product template ships without a canonical. A redesign swaps the navigation and 400 pages lose their internal links. Someone deploys the staging robots.txt, the one that says Disallow: /, to production on a Friday afternoon. The site looks perfect in a browser the whole time. Testing every significant release against a baseline catches these on day one instead of when traffic drops three weeks later.
A note on terms: "SEO testing" sometimes means SEO split testing, experiments that measure whether a change improves rankings. This guide is about release QA: making sure a deployment didn't break anything search engines depend on.
The Process in One Line
Before the Release
Write down what's supposed to change
List the expected changes and, just as importantly, what must stay the same:
| Area | Expected after release |
|---|---|
| Product titles | New pattern: Name, Key feature, Brand |
| Product canonicals | Unchanged, self-referencing |
| Category pages | Unchanged |
| Status codes | All existing 200 pages still 200 |
| Indexability | No new noindex anywhere |
| Internal links | Main navigation links unchanged |
Without this list, every difference looks equally suspicious. With it, you can sort differences into "expected" and "regression" in minutes.
Crawl production for a baseline
- Save results URL by URLTotals tell you something changed. URL-level data tells you where.
- Record the crawl settingsStart URL, scope, user agent, JavaScript rendering on or off, and URL limits. Different settings after the release mean some differences come from the crawler, not the site.
Crawl staging, if you can
- Give the crawler authenticationStaging is often password-protected. Without credentials, you'll audit a login page.
- Ignore staging's own blocks, deliberatelyStaging usually has
Disallow: /or a sitewide noindex. Configure the crawler to read past them, then note to confirm they are not present on production after release.
The Regressions That Actually Happen
Staging settings shipped to production
This is the classic one. Protections meant for staging end up live, in one of three forms:
Disallow: /
Blocks crawling of the entire site.
noindex
<meta name="robots" content="noindex"> on every template.
X-Robots-Tag
Sent by environment config, a CDN rule, or a reverse proxy. Invisible in page source.
Google generally caches robots.txt for up to about 24 hours, so a bad file can keep affecting crawling for a while after you've reverted it.
A template change with side effects
The template you changed works. The template you didn't touch, which shares a component with it, breaks:
| Check | Before | After | Change |
|---|---|---|---|
| 200 responses | 2,380 | 2,350 | -30 |
| Redirects | 70 | 100 | +30 |
| Missing H1 | 3 | 38 | +35 |
| Missing canonical | 0 | 12 | +12 |
| Noindex pages | 45 | 47 | +2 |
The release was a product page redesign. None of those changes were in the plan, and every line points at a URL list to investigate.
URL changes without complete redirects
- Exact 301sEvery old URL returns a
301to its exact new URL, not to the homepage. - No chains or loopsNo A → B → C, and nothing that circles back.
- Internal links updatedLinks point straight at the new URLs, not through redirects.
- Canonicals updatedThey reference the new URLs.
- Sitemap updatedThe XML sitemap lists the new URLs, not the old ones.
A migration where new pages load but internal links still point to old URLs works for users and wastes crawl activity on redirects for months.
Internal links quietly disappearing
A new navigation or rebuilt "related products" component can cut links with no visible sign. A category page that linked to 25 products before and 8 after still looks fine. It isn't. Compare internal link counts per URL and check for new orphan pages.
Metadata overwritten by defaults
Watch for titles or descriptions that suddenly match across hundreds of pages, like Home | Brand everywhere. That's a template falling back to a default because a variable is empty.
Comparing the Crawls
Run the after-crawl with identical settings, then compare in this order, most damaging first:
- robots.txt and indexabilityAny new noindex, header or meta, and any new robots.txt blocks.
- Status codesAny
200that became a 3xx, 4xx, or 5xx. - CanonicalsAny change, URL by URL.
- RedirectsNew chains, loops, or redirects to the wrong place.
- Internal linksLarge drops per page, new broken links, new orphans.
- Titles, descriptions, headingsUnexpected changes or new duplicates.
Also run your normal audit checks on the new crawl. If missing H1s went from 12 to 87, the 75 new ones are what this release needs to answer for.
When the Release Is a Fix
| Issue | Before | After |
|---|---|---|
| Missing titles | 42 | 0 |
| Missing canonicals | 18 | 0 |
| Broken internal links | 25 | 2 |
"The fix was deployed" isn't the same as "the problem is gone." The two remaining broken links get their own investigation, and everything else still needs a regression check. Fixes break things too.
After the Release: Watch Search Console
A crawl shows what the site serves. Search Console shows what Google does with it, and that lags by days. In the week or two after a significant release:
- URL InspectionCheck a few key changed URLs to see how Google fetches and renders them now.
- Page indexing reportWatch for jumps in "Excluded by noindex tag," "Blocked by robots.txt," or "Not found (404)."
- robots.txt reportConfirm Google has the current version.
- Performance reportCompare clicks and impressions for affected sections against the weeks before.
How Much Testing Each Release Needs
| Change | Testing |
|---|---|
| A single page's content | Check that URL by hand |
| One template | Crawl that template's URLs, before and after |
| Navigation, header, or footer | Full crawl comparison (it touches every page) |
| URL or CMS migration | Full crawl, redirect mapping check, Search Console monitoring |
| robots.txt, sitemap, or server config | Full crawl plus header checks, immediately after release |
| JavaScript framework change | Full crawl with rendering, raw vs rendered spot checks |
Keep the History
Months later, when someone asks when the canonicals broke, you can answer with a date and a release instead of a guess. Audit history also tells you whether a problem is new or has quietly existed since a migration two years ago.
Doing This With SiteAuditLint
SiteAuditLint saves every audit locally, with no limit on history, and audit comparison compares any two audits, not just the last two. For each issue it shows what's new, fixed, increased, decreased, or unchanged, down to the URLs that changed.
Scheduled SEO audits crawl on a set schedule, so there's always a recent baseline when a release goes out. Slack SEO alerts send each audit summary to your team's channel, so a spike in noindex pages the morning after a deploy doesn't go unnoticed.
Release Checklist
Before
- Expected changes and must-not-change list written down
- Baseline crawl of production saved, with settings recorded
- Staging crawled with the same settings, if available
Immediately after
- robots.txt checked on production
- No new noindex in meta tags or response headers
- Identical crawl run and compared
During comparison
- Status code and canonical changes reviewed URL by URL
- Redirects, internal links, and metadata checked
- Every difference marked expected or regression
Following week
- URL Inspection on key changed URLs
- Page indexing report and traffic watched for changes
- Comparison saved with the deployment record