Skip to content
Neaptidestudio
blog

Next.js SEO Release Checklist: Eight Tested Defects

Neaptide · October 13, 2026 · 9 min read

We injected eight defects into a Next.js fixture. A small HTTP checker caught six and missed two. Download the script, results and repeatable test.

On this page
In each round, six of eight injected defects were detected and two were missed. The separate clean control generated zero alerts.

A passing SEO release check only covers what the check can observe. On October 13, 2026, we tested a small response-HTML checker against eight deliberately injected defects in a Next.js production build. It detected six and missed two in each of two rounds. The clean control produced no alerts. The two misses explain why a release checklist also needs robots.txt and browser checks.

One control, eight defects, two rounds

We adapted the fixtures from our earlier canonical, hreflang and sitemap experiments. Each of nine scenarios had English and French product pages; each defective scenario introduced one problem. We froze the scenario list, source files, expected values and checker before requesting the pages. This was a local synthetic experiment on Next.js 15.5.22 and React 19.2.6, not an audit of nine websites.

The script checks response status, one expected canonical, generic noindex directives, a nonempty title, an H1 in response HTML, an exact hreflang map and one sitemap’s listed URLs. Title and H1 checks are explicit project contracts, not claims about universal Google indexing requirements. Expectations come from a reviewed manifest. Reading them from the page being tested would risk accepting the same mistake twice.

What the checker detected and missed

LAB-RELEASE-2026-10-13 · Next.js 15.5.22
Case / injected conditionResult in both roundsReported signal
C00 · Clean controlNo alertNone
D01 · Canonical points to the wrong domainDetectedCANONICAL
D02 · Robots meta contains noindexDetectedNOINDEX
D03 · French hreflang points to a missing routeDetectedHREFLANG
D04 · Sitemap lists an extra 404 URLDetectedSITEMAP_TARGET_STATUS
D05 · English page has no titleDetectedTITLE
D06 · robots.txt disallows the scenarioMissedNone
D07 · Product content disappears after hydrationMissedNone
D08 · HTTP X-Robots-Tag contains noindexDetectedNOINDEX
In each round, six of eight injected defects were detected and two were missed. The separate clean control generated zero alerts.
6 + 2 = 8 defects · control is separate · same result in each round

The original experiment comprised 18 checker runs and 56 HTTP responses. All findings matched between rounds. We then extracted the downloadable archive, installed its pinned dependencies and built it separately: all check values matched across another 18 runs. These repeats test reproducibility; they do not turn eight selected defects into a representative detection-rate benchmark. The same agent designed the checker, fixtures and review.

Why a green report can still accompany a broken page

In D07, the response contained the product heading and content. After JavaScript ran, the browser showed only a message saying the product content had been removed. The checker’s H1 test passed because it parsed the response and never executed JavaScript. A browser observation confirmed the missing content; this was not a Googlebot rendering test.

D07 retained product content in the HTTP response, but removed it after JavaScript ran in the browser. The HTTP-only checker passed; Google rendering was not tested.
Checker: passed · browser: missing content · Google rendering: not tested

In D06, the root robots.txt contained a rule disallowing the scenario. Ordinary GET requests still returned valid pages, and the checker did not parse robots.txt. It therefore passed this case too. Google documents crawling controls, indexing directives and rendering separately. An HTTP 200 and an absence of noindex do not establish that Google can crawl, render or index the intended content.

Run the same check and read the report

Download and extract the full test bundle. In its fixture directory, run npm ci --ignore-scripts, npm run build and npm run start. Keep that terminal running. From the extracted bundle’s root, use the command below. Python 3.9 or later is sufficient for the checker; it has no third-party Python dependencies. The README records the exact tested runtime versions.

python3 check_release.py \
  --origin http://127.0.0.1:8792 \
  --manifest manifests/control.json \
  --out control-check

Exit 0 means no covered contract failed; exit 1 means findings; exit 2 means an input or run error. Use a new output directory for each run. Replacing control.json with canonical.json produces the recorded canonical failure. For both complete rounds, run python3 collect.py and then python3 analyze.py from a fresh extraction.

This excerpt is derived from the actual D01 report. The complete report also records passed checks, response evidence and unchecked areas.

{
  "passed": false,
  "findings": [
    {
      "code": "CANONICAL",
      "url": "http://127.0.0.1:8792/canonical/en/product",
      "passed": false,
      "observed": [
        "https://wrong.example/product"
      ],
      "expected": [
        "http://127.0.0.1:8792/canonical/en/product"
      ]
    }
  ]
}

For your site, replace the sample manifest with a reviewed set of important routes and expected values. The script only requests the supplied origin, follows no redirects and supports one sitemap urlset, up to 100 explicit pages and 30 sitemap locations. It does not validate translation quality or all hreflang relationships. Complex user-agent-specific X-Robots syntax, sitemap indexes and browser behavior are outside its validated scope.

A release workflow beyond this script

Use the report as one evidence file in a release decision. The table below is our proposed workflow, not an experimentally validated release policy. Staging may intentionally use authentication or noindex. Review expectations for each environment; do not remove those protections merely to make a check pass.

A release workflow beyond this script
StageOwner / checkEvidence to retain
Before releaseDeveloper and SEO owner review expected routes, canonical URLs and available translationsVersioned manifest; known exclusions; comparison with the previous build
Release candidateRun HTTP checks, separately review robots rules and inspect important pages after JavaScriptJSON report; robots review; browser evidence of content and links
After deploymentRepeat against public routes; investigate changes in Search Console and analytics when access is availablePublic response/render checks; actual indexing and performance data with dates

Script, fixture and research data

This hand-selected lab does not establish a real-world detection rate, a complete SEO audit or prevention of traffic loss. A silent control is evidence about this control only. We measured no Google indexing, rankings, leads or AI citations. Search demand for the topic was not quantified. Our conclusion is limited to the supplied checker version and fixtures.

The fixture preserves older pinned dependencies for reproduction. Its fresh installation reported three dependency advisories. Keep it on loopback as documented; it is not a production starter. Review current dependency advisories before adapting the code.

faq

The short version

Does a passing SEO release check mean Google can index the page?

No. This checker reads HTTP responses and an explicit manifest. It does not execute JavaScript, evaluate robots.txt or inspect Google’s index. Our two missed defects show why those checks remain separate.

Can I use the script in CI?

Yes, after reviewing the manifest, supported syntax and limits for your project. Treat exit codes as covered contract results. Run it against a reachable build and retain the JSON report; add the browser, robots and other checks your release requires.