blumenjs 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -212,6 +212,14 @@ export function RouterProvider({
|
|
|
212
212
|
return () => window.removeEventListener("popstate", onPopState);
|
|
213
213
|
}, []);
|
|
214
214
|
|
|
215
|
+
// Track whether hydration is complete. During hydration, we skip
|
|
216
|
+
// Suspense because the lazy chunk hasn't loaded yet and Suspense
|
|
217
|
+
// would show a fallback that mismatches the server HTML.
|
|
218
|
+
const [hydrated, setHydrated] = useState(false);
|
|
219
|
+
useEffect(() => {
|
|
220
|
+
setHydrated(true);
|
|
221
|
+
}, []);
|
|
222
|
+
|
|
215
223
|
// ── Render ──────────────────────────────────────────────────
|
|
216
224
|
const contextValue: RouterContextValue = { path, params, navigate };
|
|
217
225
|
|
|
@@ -220,6 +228,19 @@ export function RouterProvider({
|
|
|
220
228
|
// 2. Otherwise — show the page component
|
|
221
229
|
const LoadingComp = loadingComponent;
|
|
222
230
|
|
|
231
|
+
// During initial hydration, render App directly (no Suspense/ErrorBoundary)
|
|
232
|
+
// to match the SSR output exactly. After hydration, wrap with Suspense
|
|
233
|
+
// for lazy-loaded navigation.
|
|
234
|
+
const pageContent = hydrated ? (
|
|
235
|
+
<BlumenErrorBoundary>
|
|
236
|
+
<Suspense fallback={LoadingComp ? <LoadingComp /> : <DefaultLoading />}>
|
|
237
|
+
<App Component={PageComponent} pageProps={pageProps} />
|
|
238
|
+
</Suspense>
|
|
239
|
+
</BlumenErrorBoundary>
|
|
240
|
+
) : (
|
|
241
|
+
<App Component={PageComponent} pageProps={pageProps} />
|
|
242
|
+
);
|
|
243
|
+
|
|
223
244
|
return (
|
|
224
245
|
<RouterContext.Provider value={contextValue}>
|
|
225
246
|
{isLoading && LoadingComp ? (
|
|
@@ -230,11 +251,7 @@ export function RouterProvider({
|
|
|
230
251
|
<div
|
|
231
252
|
className={`page-transition ${transitioning ? "page-transition-exit" : "page-transition-active"}`}
|
|
232
253
|
>
|
|
233
|
-
|
|
234
|
-
<Suspense fallback={LoadingComp ? <LoadingComp /> : <DefaultLoading />}>
|
|
235
|
-
<App Component={PageComponent} pageProps={pageProps} />
|
|
236
|
-
</Suspense>
|
|
237
|
-
</BlumenErrorBoundary>
|
|
254
|
+
{pageContent}
|
|
238
255
|
</div>
|
|
239
256
|
)}
|
|
240
257
|
</RouterContext.Provider>
|
|
@@ -342,8 +342,9 @@ async function handleRender(
|
|
|
342
342
|
};
|
|
343
343
|
|
|
344
344
|
// Render React to HTML
|
|
345
|
-
//
|
|
346
|
-
//
|
|
345
|
+
// Must match the client's INITIAL hydration tree exactly:
|
|
346
|
+
// div.page-transition > App
|
|
347
|
+
// (Client adds Suspense/ErrorBoundary AFTER hydration via useEffect)
|
|
347
348
|
const appElement = React.createElement(
|
|
348
349
|
"div",
|
|
349
350
|
{ className: "page-transition page-transition-active" },
|