A recurring problem when doing SSR are so-called hydration mismatches.
We recommend having a clear understanding of what hydration is, see the What is hydration? guide.
A hydration mismatch is when the content rendered to HTML in Node.js is not the same than the content rendered in the browser.
Hydration mismatches can induce performance degradation and bugs and should therefore be avoided.
Let's imagine we render the current date's milliseconds:
<span>{ new Date().getMilliseconds() }</span>
This induces a hydration mismatch
because the milliseconds rendered to HTML
(e.g. <span>123</span>
)
won't match the milliseconds rendered on the browser-side
(e.g. <span>167</span>
).
To prevent the hydration mismatch, we should ensure that the same milliseconds value is rendered.
We can do that by using the onBeforeRender()
hook.
export { onBeforeRender }
async function onBeforeRender() {
const milliseconds = new Date().getMilliseconds()
return {
pageContext: {
milliseconds
}
}
}
<span>{ pageContext.milliseconds }</span>
What happens here is that pageContext.milliseconds
will be set exactly once, so that the same milliseconds value will be rendered to HTML in Node.js and hydrated on the browser-side. (We use export passToClient = ['milliseconds']
to pass pageContext.milliseconds
to the browser.)
Common causes:
With React:
Warning: Text content did not match.
. Make sure to use the latest React version.With Vue:
ensureHydration: true
option because Vue always needs the first render to be a hydration. (In other words, the first render should never be interrupted: a client-side routing trigged by the user clicking on a link should await hydration before proceeding instead of interrupting the hydration process.)There are situations when mismatches are inevitable. To suppress hydration mismatch warnings: