Fixing Meta Tags Overwritten During Hydration
A server-rendered page can ship the correct <title> and meta description, then lose them a moment later: during hydration the client component mounts with default metadata — before the route’s data resolves — and overwrites the server’s tags. If a crawler captures the DOM in that window, it indexes the defaults. This is a hydration-timing bug, and it is the core failure that avoiding metadata hydration pitfalls addresses.
Step-by-step fix
-
Confirm the overwrite. Compare the head in the server response with the head after hydration.
// In the console right after load: document.title // is it the route's title, or a default like "My App"? -
Hydrate metadata from the same data the server used. The client’s first render must compute the same title/description, so hydration is a no-op for the head.
// ❌ Client mounts with a default, then updates after fetch → overwrite + flash useEffect(() => { document.title = data?.title ?? 'My App'; }, [data]); // ✅ Title derived from data present at first render (passed from the server) function ProductMeta({ product }) { useServerInsertedHead(() => <title>{product.name}</title>); return null; } -
Do not render placeholder meta on the first client pass. If data is not ready, render nothing for the head rather than a default that overwrites the server value.
-
Mutate, don’t replace, the tags so hydration reconciles cleanly instead of tearing down and rebuilding the head.
Validation
document.titleafter load equals the server-rendered title, with no flash.- GSC URL Inspection rendered HTML shows the correct title and description.
- No console hydration warning for the metadata components.
- Throttled CPU reload shows no visible default-then-correct title flash.
Reference
// Pass server data to the client so first render matches — no overwrite
export function Head({ meta }) {
// meta is serialized from the server render and available on first client render
return (
<>
<title>{meta.title}</title>
<meta name="description" content={meta.description} />
<link rel="canonical" href={meta.canonical} />
</>
);
}
Frequently Asked Questions
Why do my meta tags reset to defaults after the page loads? The client re-renders during hydration with default metadata before the route’s real data is available, overwriting the correct server-rendered tags. The fix is to compute the same metadata on the client from the same data the server used, so the first client render matches.
Does a brief meta flash hurt SEO? If a crawler snapshots the DOM during the default-value window, it can index the wrong title or description. Even when it does not, the flash signals that client metadata is not aligned with the server, which is a fragile state worth fixing.
Related
- Avoiding Metadata Hydration Pitfalls — the full hydration-metadata guide.
- Reducing layout shift during React hydration — the visual counterpart of hydration mismatch.
- Programmatic Title & Meta Tag Updates — managing the head across navigation.
← Back to Avoiding Metadata Hydration Pitfalls