Summary
Filed after hitting askrjs/askr#133 (fixed in 0.0.71): a <For> reconciliation bug where the SSG-rendered static HTML was byte-correct, and the bug only manifested after client JS hydrated — an element silently migrated into an unrelated sibling's DOM container. Nothing about that bug was visible in the shipped HTML, in a diff, or in any test that checks rendered markup against expected output; it only showed up by opening a real browser, hydrating, and inspecting the live DOM.
I also (separately, in the same app) found and fixed a latent version of a related hazard (an early return null that skips a <For> call, structurally identical to the ternary case in askrjs/askr#146) that I could not get to reproduce live, precisely because I had no tooling to drive it — I had to reason about it by hand and verify by temporarily reverting the fix, rebuilding, and manually clicking through the app in a real browser via browser automation.
The ask
Some form of automated check — could live in analyze, check, or as a new command — that:
- Builds the SSG output for a route (or a set of routes),
- Serves it and drives a real (or headless) browser to hydrate it,
- Diffs the DOM structure immediately post-hydration against the DOM structure of the same route rendered fresh client-side (no SSR/hydration involved) or against the pre-hydration static HTML's structure,
- Flags any route where those diverge.
This is exactly the shape of bug that's cheap to catch mechanically (diff two DOM trees) and expensive to catch by hand (requires knowing to open a real browser and inspect live nodes, which nothing in the normal build/ssg/check pipeline currently prompts a developer to do). Given askr ssg already generates every route and askr presumably has hydration-verification code internally (I found a verify-hydration chunk referenced in the built client bundle, so there may already be relevant machinery to build on), this might be a smaller lift than it sounds.
Environment
@askrjs/cli: 0.0.11 (or 0.0.12, per askr outdated — hadn't updated at time of filing)
@askrjs/askr: 0.0.73
Summary
Filed after hitting askrjs/askr#133 (fixed in 0.0.71): a
<For>reconciliation bug where the SSG-rendered static HTML was byte-correct, and the bug only manifested after client JS hydrated — an element silently migrated into an unrelated sibling's DOM container. Nothing about that bug was visible in the shipped HTML, in a diff, or in any test that checks rendered markup against expected output; it only showed up by opening a real browser, hydrating, and inspecting the live DOM.I also (separately, in the same app) found and fixed a latent version of a related hazard (an early
return nullthat skips a<For>call, structurally identical to the ternary case in askrjs/askr#146) that I could not get to reproduce live, precisely because I had no tooling to drive it — I had to reason about it by hand and verify by temporarily reverting the fix, rebuilding, and manually clicking through the app in a real browser via browser automation.The ask
Some form of automated check — could live in
analyze,check, or as a new command — that:This is exactly the shape of bug that's cheap to catch mechanically (diff two DOM trees) and expensive to catch by hand (requires knowing to open a real browser and inspect live nodes, which nothing in the normal
build/ssg/checkpipeline currently prompts a developer to do). Givenaskr ssgalready generates every route andaskrpresumably has hydration-verification code internally (I found averify-hydrationchunk referenced in the built client bundle, so there may already be relevant machinery to build on), this might be a smaller lift than it sounds.Environment
@askrjs/cli: 0.0.11 (or 0.0.12, peraskr outdated— hadn't updated at time of filing)@askrjs/askr: 0.0.73