Make Server Rendering and Hydration Agree
R068 is what happens before JavaScript: a crawler receives the server HTML, sees an empty app shell, and leaves without your page copy or preview metadata. R067 is what happens after: the browser renders a different first tree from the server and React has to repair the disagreement.
Server-side rendering and hydration are one path. Test both ends.
Check the response crawlers receive
Use View Source or fetch the page without running JavaScript. The response should contain:
- the meaningful first-screen heading and copy;
- canonical URL;
- title and description;
- Open Graph or other preview metadata;
- links that work before client code loads;
- no private user data from a shared cache.
The Elements panel is not this test. It shows the document after JavaScript has changed it.
Make the first render deterministic
The server and client need to produce the same markup for hydration. Common mismatches include:
Date.now()or locale formatting during render;Math.random()or generated IDs;- reading
localStorageonly in the browser; - checking viewport size during render;
- different feature flags or authentication state;
- invalid HTML the browser silently repairs.
Move browser-only reads into an effect after mount, or pass the server's value to the client as serialized initial state. Use stable ID APIs designed for SSR. Do not hide the warning with a suppress flag unless the difference is narrow, intentional, and safe.
Visible is not the same as interactive
The server HTML can show a button before its JavaScript handler is attached. During that gap, the page is visible but not hydrated. Avoid UI that looks ready while required handlers or state are not ready. Prefer real links for navigation and progressively enhanced forms when practical.
Test a slow device and network. Click during hydration, not only after the page settles.
One verification matrix
- Fetch raw HTML and confirm crawler-visible content.
- Load with JavaScript disabled and inspect the useful baseline.
- Load with JavaScript enabled and capture every hydration warning.
- Compare server markup with the client's first render inputs.
- Test clocks, locale, random IDs, local storage, and auth edges.
- Check the social preview using the final public URL.
- Interact during a throttled hydration window.
Claude can compare the two render paths and identify nondeterministic code. Browser tests and raw responses prove the fix.
Run the starter locally
npm test
npm run validate
npm run sample
The safe workflow validates fictional server and client evidence. n8n and Docker are included for orchestration, but the pack does not deploy or modify a page.