SolidStart hydration guard: keep SSR/CSR output identical, gate browser-only APIs, use stable IDs, align Suspense/resource fallbacks, and use clientOnly/onMount for client-only UI.
window, document, localStorage, matchMedia, ResizeObserver with if (!isServer) or typeof window !== "undefined".Math.random(), Date.now() in render; use createUniqueId() or values passed from server data.isServer unless the client version is wrapped in clientOnly or <NoHydration>.createUniqueId() inside components, or pass stable IDs from server data/props.createUniqueId() the same number of times on server and client; donβt gate it behind isServer or <NoHydration>.createResource/router createAsync, keep initialValue consistent between server and client.ssrLoadFrom: "server" when you need the server-rendered HTML to match hydration; "initial" will re-fetch on the client.onHydrated to inspect resource values during hydration when debugging.<Hydration> or pass it through props.deferStream only when you can set headers/status before flush; otherwise keep data in initial render to avoid mismatch.clientOnly and provide a SSR-safe fallback.onMount or createEffect gated by !isServer.<Portal> is client-only with hydration disabled; use it for overlays that should not hydrate.<NoHydration> skips hydration for its subtree; use <Hydration> to resume for interactive islands when needed.renderToStream), set HttpHeader/HttpStatusCode before first flush; hydrate assumes status/headers are fixed.<FileRoutes /> with <Suspense> in the Router root to avoid hydration errors.preload functions pure; SSR runs them and resumes on the client during hydration.<HydrationScript /> once (SolidStart injects it via the document assets slot).<Suspense> and that fallbacks match server/client.Math.random(), Date.now()).createUniqueId() call counts are identical on server/client.clientOnly, <NoHydration>, or <Portal>.