Did the SEO fix work? Pair before-and-after evidence without hiding regressions
Two title warnings disappear after a template fix. Has the repair passed? Not if the same change sends a Chinese page’s related link to English, or a failed fetch quietly removes a URL from the report.
The useful question after a repair is what changed on each original URL under the same check? Start with a confirmed batch from the batch audit grouping guide, then keep every original URL in the comparison. A smaller issue total is a clue; paired observations explain it.
Freeze the comparison before changing anything
Save the original input list, raw responses and check definitions. Record the capture time, request settings, environment, rule version and completion count. If an audit service cannot export raw rows, save its visible findings and completion state, and identify the checks you can independently reproduce. Do not imply that a local script reproduces the service’s score.
Use the same URL, locale and rule as the comparison key. Preserve query strings and trailing slashes until you have established that they are equivalent for this check. Keep a redirecting input URL separate from its final destination: otherwise two inputs can collapse into one apparently successful row. The redirect diagnosis walkthrough explains how to identify that delivery layer.
A compact record can look like this:
input_url, locale, rule_id, rule_version, captured_at
http_status, final_url, raw_evidence_path, observed_value
When the environment or rule changes, annotate the difference and establish a comparable baseline before attributing a result to the repair. A checksum helps prove that the input list stayed the same; it does not prove that the requests saw equivalent content.
Reproduce a repair that should still fail acceptance
This example was run on November 4, 2026 with Node v26.4.0 and the repository-installed node-html-parser. It is a deliberately constructed local HTTP lab, not a Fennec app audit export, customer case or production experiment. The checker reads response HTML; it does not execute JavaScript or inspect Google’s index.
The lab requests five paths in three successive states. Two English pages initially repeat | Demo in their titles. The Chinese page, an exception page and a retry sample start clean. Two exact checks run on every successful HTML response: whether the title ends with | Demo | Demo, and whether the related anchor points to the other language’s path prefix. These are fixture-specific checks, not universal SEO rules or title-writing advice.
Use the lab script and captured observations to reproduce the example:
mkdir seo-retest-lab
cd seo-retest-lab
npm init -y
npm install [email protected]
# Save the linked script here as capture.mjs.
node capture.mjs
Use Node.js with built-in fetch support (Node 18 or later). In a new folder, install the parser version used by this example, then save the linked script as capture.mjs before the final command. The script starts a loopback server on an available port, makes actual HTTP requests, writes each response plus observations.json, and closes the server. It does not require credentials or a remote site. Inspect the script before running it; rerunning replaces the generated captures.
| Input path | Baseline | Candidate repair | Corrected rerun |
|---|---|---|---|
/en/a/ | Duplicate title suffix | Title fixed | Title fixed |
/en/b/ | Duplicate title suffix | Title fixed | Title fixed |
/zh/a/ | Correct locale link | Link goes to /en/a/ | Link stays at /zh/a/ |
/en/exception/ | Both checks pass | Both checks pass | Both checks pass |
/en/retry/ | Both checks pass | HTTP 503; checks unknown | HTTP 200; both checks pass |
The candidate repairs the two title findings but creates a wrong-language link and loses one readable response. It is not acceptable for this defined batch. The corrected rerun restores the Chinese destination and the failed response while retaining both title repairs.
Pair rows before counting outcomes
Join the two captures on the stable key; keep unmatched rows rather than silently using an inner join. For every original URL and rule, classify the observation:
| Before | After | Interpretation |
|---|---|---|
| Fails | Passes | Fixed for this check |
| Fails | Fails | Still failing |
| Passes | Fails | Regression |
| Passes | Passes | Unchanged pass |
| Missing or unreadable | Any state, or vice versa | Unknown; investigate coverage |
In the lab, five URLs times two rules produce ten comparison rows. The candidate has 2 fixed, 1 regression, 2 unknown and 5 unchanged passes. The corrected rerun has 2 fixed and 8 unchanged passes, with no regressions or unknowns. The two unknown rows represent one failed URL, not two failed requests. Both checks are unknown on its 503 response.
Do not convert null into “no issue.” First verify the request succeeded and returned the expected document. A 200 challenge page or login screen can also be unusable evidence. Fetch the missing sample again and retain the earlier failure; do not erase it from the record. For a real site, also record rendering mode, redirects and meaningful content differences that this small fixture does not model.
Add controls that can reveal collateral damage
The two repaired title samples answer whether the intended defect disappeared. The Chinese sample checks a neighboring language boundary. The exception checks that an unaffected route still behaves as expected. The retry sample exposes incomplete coverage.
Choose controls from the actual change boundary: another template, locale, pagination state or intentional override. Five local samples do not establish that a whole production site is correct. For broader batches, repeat the same rules across the frozen URL set and expand human review where templates differ. The prioritized fix workflow helps decide which verified regression needs action first.
Inspect actual anchor destinations as well as visible wording. Google’s link guidance describes crawlable anchors and useful anchor text. A same-language path prefix is only this lab’s expectation: real multilingual sites can use other URL structures or intentional language switching. Run a link check and verify the expected destination for the real user journey.
Keep technical acceptance separate from Google observation
For this local batch, acceptance requires every input to return its expected document, both title repairs to remain, the Chinese link to stay correct and the controls to keep passing. Store the raw evidence and the rule version with that conclusion. Then check the real release’s build, rendering, links and indexing directives before describing production behavior.
Use the SEO audit worksheet to preserve that evidence alongside the change. If the repair affects canonical URLs, follow Google’s canonical guidance and inspect the relevant signals; this title-and-link fixture does not test canonical selection.
Google-side processing is a separate observation. The URL Inspection documentation explains indexed and live-test views. A local passing check cannot establish that Google has recrawled, selected a canonical, indexed the page or improved its ranking. Close the technical repair only to the scope your evidence covers, and observe search outcomes separately.