From 08a3ae2ef1e723e4687f410f81422209d1df0c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Thu, 16 Jul 2026 20:03:58 +0200 Subject: [PATCH] fix(dashboard): pin the Today hero to the skeleton during hydration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The digest query rehydrates from the persisted client cache, so the Today hero was painting on the first client render while the server had rendered the skeleton — a text-content hydration mismatch (React #418) that the dashboard e2e's no-significant-errors gate caught. Gate the hero on `mounted` like the rest of the dashboard's late-hydrating surfaces, so SSR and the first client render both show the skeleton and the hero appears once mounted. --- src/app/page-client.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/app/page-client.tsx b/src/app/page-client.tsx index d358a5a6c..e8e193e7b 100644 --- a/src/app/page-client.tsx +++ b/src/app/page-client.tsx @@ -793,7 +793,12 @@ export default function DashboardPageClient() { degrades to nothing (the hero itself returns null). The dense tile grid + charts below are untouched. */} {insightsEnabled && - (digestQuery.isLoading ? ( + // `!mounted` pins the SSR pass AND the first hydration render to the + // skeleton (v1.16.4 pattern): the digest query rehydrates from the + // persisted cache on the client, so without this gate the client's + // first render would paint the hero while the server rendered the + // skeleton — a text-content hydration mismatch (React #418). + (!mounted || digestQuery.isLoading ? ( ) : digestQuery.data ? (