| Advice on the "A Broken DOM" section: it sounds exactly like a hydration mismatch. Hydration is the process of React correlating existing DOM nodes from server-rendered HTML (SSR) with the initial render of the React app on the browser-side. (As opposed to what happens without SSR, which is almost always the app being rendered into an empty DOM node – no content exists yet.) Satisfying hydration constraints is by far the hardest part of doing React server-side rendering. The basic requirement is: whatever HTML you rendered on the server, the initial render of the browser app MUST output that exact same DOM structure. Otherwise, it won't be able to correlate them correctly, and will get confused about which DOM nodes to update. You can seriously mangle your entire page this way – but usually, it looks like nearby content stuck in the wrong place, or incorrect updates. Some things that lead to hydration mismatches: - Time-based rendering. Time passes between when the server rendered the HTML and the browser initializes the app. So any component using `new Date` to make decisions can potentially have a hydration mismatch. - Randomization. Let's say you wanna choose a random promo image to show. The `Math.random()` result is going to be different on the server and client. - Anything involving browser APIs, like the browser window size, or checking `typeof window`, etc. The server has no access to this info, so it either needs to skip rendering that content, or fallback to a default. Once in the browser, here's the important part: you need the app's components to make all the same rendering decisions that they made on the server, on the first pass specifically (when hydration occurs). Then, using the component lifecycle, you can make them update to take the latest client-side info into account. In other words, it's not enough to simply detect `typeof window` and render different content – you're only "allowed" to render that different content after the app has done its initial mount. The somewhat-reassuring aspect of all this is that it's almost certainly your components at fault, not Gatsby or React, so it can always be fixed without too much effort. But it's an annoying foot-gun to have to worry about nonetheless. |