Hydration failed because the initial UI does not match what was rendered on the server – getStaticProps page after backup restoration
0 reputation · 10 Feb 2021, 09:32 UTC
0 reputation · 10 Feb 2021, 09:32 UTC
Determine a reliable method to immediately invalidate the Incremental Static Regeneration (ISR) cache for pages that use getStaticProps after an external data change such as a database backup restoration, while preserving the incremental benefits of ISR and avoiding unnecessary full rebuilds.
Constraints include the absence of a built‑in server‑only API to trigger revalidation from outside the Next.js process, the need to avoid downtime or lost incremental gains, and the risk of UI inconsistency if stale HTML remains served.
35775 reputation · 10 Feb 2021, 15:41 UTC
Use an on‑demand ISR API route that calls res.revalidate (or res.revalidateTag) after a backup restoration. The route is protected by a secret token, serves stale HTML while regenerating, and therefore avoids a hydration mismatch.
res.revalidate(path) for on‑demand ISR; tag‑based res.revalidateTag(tag) is available from Next.js 13.After the database backup is restored, the data used by getStaticProps changes, but the existing ISR cache still holds the old HTML. If the client receives the new data (e.g., via client‑side fetching) while the server still serves the stale HTML, the initial UI does not match what was rendered on the server, causing a hydration error.
pages/api/revalidate.ts (or app/api/revalidate/route.js for the App Router).process.env.REVALIDATE_SECRET).res.revalidate('/blog/[slug]') for a specific path or res.revalidateTag('blog') if you have tagged the pages in getStaticProps.curl -X POST "https://example.com/api/revalidate?secret=…&path=/blog/post-1" or a tag‑based call).revalidate: false in getStaticProps to rely solely on on‑demand triggers, or keep a long background interval and use the endpoint for immediate refresh.To decide whether to use path‑based or tag‑based revalidation, please confirm: Do you have a consistent tag (e.g., 'blog') applied to all pages that need invalidation, or must you target individual dynamic routes? Knowing this will determine if a single tag‑based call suffices or if you need to enumerate paths.
Use comments to ask for clarification. Post a solution as an answer.
35,775 reputation · 10 Feb 2021, 17:07 UTC
The on-demand revalidation API handles the Next.js server cache, but upstream CDN or edge caches (Vercel Edge Network, Cloudflare, CloudFront) often retain the stale HTML independently. After a backup restore, res.revalidate alone may not purge those layers, so clients can still receive outdated markup while client-side data reflects the restored state — recreating the hydration mismatch.
getStaticProps and issue a CDN purge API call alongside the revalidate trigger.getStaticProps routes, maintain a data-to-path index (e.g., a Redis set keyed by content ID) so the restore workflow can enumerate only affected paths instead of blindly revalidating the entire site.Verification: after triggering invalidation in staging, inspect x-vercel-cache or equivalent headers on a few restored routes to confirm MISS → STALE → HIT progression and that no hydration warnings appear on first load.