
303 Routes, 0 Red Gates: Static Export Still Needs a Preflight
A green build is not release clearance. The artefact needs its own route, metadata, link, and visual checks.
The build output is the deployment candidate.
- Treat out/ as the release candidate.
- Fail the export when an indexable page loses its H1 or social image.
- Check a dynamic route from the built tree, not only next dev.
- Publish the evidence with the hand-off, not after a crawler finds the miss.
At the opening measurement for this field note, AutoKaam's release-equivalent verification run produced 303 generated routes and reported no hard-gate failure. That is a useful baseline, not a trophy. A new article can change the count; a new category can change it again. The number only earns meaning when the generated tree is checked for the things a static host and a crawler actually receive.
This is the distinction teams often miss when they say a site is "built." A successful framework build says the renderer completed its job. It does not automatically prove that a link resolves from the exported HTML, that a page keeps exactly one H1, that a collection page retains a social-preview image, or that a keyboard user can close a mobile menu. Those are release properties, not compiler properties.
The preflight for this update starts with npm run lint, npm run typecheck, unit tests, and the corpus-content gate. It then runs npm run build and npm run audit:export against the generated out/ directory. The audit is intentionally separate from the build because it reads the artefact rather than trusting source-level intent.
Why 303 is a baseline, not a KPI
The route count came from the build before this field note was added. That timing matters. Content sites are supposed to gain and retire URLs. Chasing an unchanged count would turn a healthy release into a cosmetic metric.
What should remain stable is the release contract:
- every expected dynamic route is enumerated at build time;
- every indexable page has a single H1;
- canonical, description, and Open Graph data are present in the rendered head;
- social-image URLs are absolute and their local files exist in the output;
- internal links resolve in the exported tree; and
- the homepage and a narrow viewport still look intentional when served as static files.
This is the practical consequence of Next.js static export. The framework writes HTML and supporting files at build time. A static host serves those files. There is no request-time application server waiting to repair a missing route or complete a metadata object.
The quiet failure: nested metadata replacement
The most valuable fix in this pass was not a headline rewrite. It was a shared metadata guard.
Next.js can compose metadata through a layout hierarchy, but nested fields such as openGraph are replaced when a child route supplies its own object. A page can therefore inherit a root description while silently losing the root images array. The source code looks reasonable. The rendered <head> has no og:image.
The generateMetadata documentation describes the merge behaviour. The operational response is simple: any route that writes openGraph should explicitly write an image, and the export audit should fail if an indexable page has no Open Graph image or has a non-absolute image URL.
That moves the issue from a social-platform surprise to a local regression. It also protects the 82 hub-style routes that were previously relying on shallow inherited metadata. The fix is shared, but the proof stays route-level: inspect the generated HTML after every meaningful metadata change.
Crawl readiness is more than a title tag
Technical SEO is strongest when the page structure says the same thing in several machine-readable ways. A news article should have a clear H1, a canonical URL, a description that matches the actual story, article dates, and structured data that identifies the author, publisher, and image. Google's Article structured-data guidance is the right reference for that article-specific layer.
The preflight does not claim that a page will rank. No local command can promise that. It can prove narrower, more honest things:
- the static artefact includes the metadata a crawler needs to interpret;
- the referenced image file exists and can be fetched from the generated site;
- internal navigation does not lead to a missing page; and
- the content has enough primary or authoritative sources for a reader to inspect the underlying claim.
My technical SEO threshold is narrower and more useful: make the site legible and robust without pretending that an audit tool controls search demand, competition, or indexing cadence.
Visual readiness belongs in the same preflight
Static websites fail visually in very ordinary ways: a lead image is present in data but absent from the layout, a status badge implies a live feed despite a dated export, or a menu works with a pointer but leaves keyboard focus stranded. None of these are content-model failures. All of them change whether the site feels trustworthy.
For this pass, the homepage lead now renders its real self-hosted cover image. The persistent status language now says "verified" rather than presenting a static edition as live. The mobile navigation opens onto a focusable link, keeps Tab focus within the menu, and returns focus to its trigger on Escape. These are small details, but they are the difference between an editorial system and a poster.
The local static server is the right place to check them. Serve out/, open the homepage at desktop and mobile widths, use a keyboard, then sample a recent article and a dynamic tutorial route. This catches output-only mistakes before a deployment gives them a public URL.
The release hand-off should contain evidence
The next move after a green preflight is not "assume production is fine." It is to hand off the static artefact together with the checks that produced it. The package is small and concrete: changed files, the build result, the export-audit result, known remaining content debt, and the exact out/ directory that a deploy would consume.
For a full build checklist, read Next.js Static Export: A Release Preflight for Cloudflare Pages. For the broader framework choice, App Router vs Pages Router in 2026 explains when static export is a fit. AutoKaam's methodology describes how source-backed field notes and reviews are assembled.
The durable conclusion is straightforward: a green build is necessary, but the exported tree is the thing that ships. Count its routes if the number helps you notice drift. Audit its links, metadata, image assets, and interaction states because those are the failures readers and crawlers will actually see.
Topics
More from the same beat.
GLM-5.2 Cleared the Six Hard Tasks I Use to Vet Any Cheap Model
A new open-weights model matched my flagship on objective hard tasks. The battery I run before trusting any cheap model in production did not change.
- A leaderboard rank is a reason to test a model, not a reason to trust it. I keep a fixed battery of objective hard tasks with execution-checked answers and run it on every cheap or open release bef…
GLM-5.2 Ships 753B Open Weights. My GTX 1660 Holds 6 GB.
The most powerful open-weight model of mid-June 2026 needs a cluster. A 4B model on a 6 GB card taught me what that headline leaves out.
- Open weights and a model you can run are two different claims. GLM-5.2 ships MIT weights at over 750 billion parameters, and none of that helps a 6 GB card.
Claude Code v2.1.172 Unlocks Recursive Sub-Agents. My Fleet Found Three Walls.
Recursive sub-agents are a real upgrade, and after weeks of running CLI agent fleets in tmux, I can tell you exactly where the orchestration breaks.
- Recursion is real, but it is not magic. v2.1.172 lets a sub-agent fan out its own sub-agents five levels deep, which means level two can quietly multiply your concurrency and your bill at the same …