Server rendering
Every component renders on a server, as the pages of this site do, and hydrates in the browser without a mismatch. Preact doesn’t warn about mismatches: when it hydrates, it keeps the server’s attributes, so a component that renders differently in the browser shows a mix of both.
RulesLink to this section
- The first render is the same on the server and in the browser. Don’t read
localStorage,window,matchMedia, the date or random numbers while rendering or in auseStatedefault. Read them after mounting: inuseLayoutEffectwhen they change what’s drawn, otherwise inuseEffect. - Browser APIs belong in effects and event handlers. Exported functions that touch the page, such as
setTheme, do nothing on a server. - IDs come from
useId, which matches on the server and in the browser. - When saved state changes the first paint, use a small inline script.
themeScriptis the one for the theme: it setsdata-themeanddata-theme-choiceon the page as it loads, so CSS draws the right theme and toggle icon before any JavaScript runs.ThemeTogglerenders it too, andapplyStoredTheme()runs the same code.
TestsLink to this section
src/hydration.test.tsx checks every component. It renders each one on the server, with no browser APIs available, then hydrates that HTML in a browser whose saved state differs, and expects the same HTML as rendering in the browser alone. Add new components to its list.
design-system is a Ben Hodgson projectGitHub