Cache components and react compiler
This commit is contained in:
@@ -1,20 +1,22 @@
|
||||
import type { ReactNode } from "react";
|
||||
import { Suspense, type ReactNode } from "react";
|
||||
import ConditionalNavigation from "../components/navigation/ConditionalNavigation";
|
||||
import { MessagesProvider } from "../contexts/MessagesContext";
|
||||
import { AuthModalProvider } from "../contexts/AuthModalContext";
|
||||
import messages from "../../messages/en/index";
|
||||
|
||||
// Reads the session for admin chrome (matches the HttpOnly cookie on first
|
||||
// HTML response). Scoped here so `(marketing)` can render statically.
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
// `force-dynamic` removed in favor of `experimental.cacheComponents` (Next 16).
|
||||
// See `(app)/layout.tsx` for the matching `<Suspense fallback={null}>` rationale
|
||||
// — the fallback can't access `usePathname()` since it sits in the static shell.
|
||||
//
|
||||
// Operator/admin dashboards (e.g. `/monitor`) intentionally render without the
|
||||
// public marketing footer. Auth/access is enforced upstream.
|
||||
export default function AdminLayout({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<MessagesProvider messages={messages}>
|
||||
<AuthModalProvider>
|
||||
<ConditionalNavigation />
|
||||
<Suspense fallback={null}>
|
||||
<ConditionalNavigation />
|
||||
</Suspense>
|
||||
<main className="flex-1">{children}</main>
|
||||
</AuthModalProvider>
|
||||
</MessagesProvider>
|
||||
|
||||
+14
-8
@@ -1,15 +1,19 @@
|
||||
import type { ReactNode } from "react";
|
||||
import { Suspense, type ReactNode } from "react";
|
||||
import ConditionalNavigation from "../components/navigation/ConditionalNavigation";
|
||||
import { MessagesProvider } from "../contexts/MessagesContext";
|
||||
import { AuthModalProvider } from "../contexts/AuthModalContext";
|
||||
import messages from "../../messages/en/index";
|
||||
|
||||
// Reads `cr_session` via Server Components on every navigation so the header
|
||||
// matches the HttpOnly cookie on the first HTML response (no "Log in" flash
|
||||
// before `/api/auth/session`). Scoped here instead of the root layout so
|
||||
// `(marketing)` can render statically.
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
// `force-dynamic` removed in favor of `experimental.cacheComponents` (Next 16).
|
||||
// `ConditionalNavigation` reads `cr_session` server-side (and `usePathname()`
|
||||
// transitively in `ConditionalNavigationClient`) — both are uncached, so it
|
||||
// lives behind a `<Suspense>` boundary so the rest of the layout stays in the
|
||||
// static shell while the session/pathname-aware nav streams in. The fallback
|
||||
// is `null` because any non-null fallback would also need to live in the
|
||||
// static shell, and the nav's chromeless decision depends on the pathname
|
||||
// (e.g. `/create/*` and `/login` render no top-nav). Brief blank-nav while
|
||||
// the dynamic island resolves is acceptable on signed-in product surfaces.
|
||||
//
|
||||
// Signed-in product surfaces (`/create/*`, `/login`) run without the marketing
|
||||
// footer. `/profile` adds it via `profile/layout.tsx`. Per-route chrome (e.g.
|
||||
// CreateFlow) is composed in nested layouts.
|
||||
@@ -17,7 +21,9 @@ export default function AppLayout({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<MessagesProvider messages={messages}>
|
||||
<AuthModalProvider>
|
||||
<ConditionalNavigation />
|
||||
<Suspense fallback={null}>
|
||||
<ConditionalNavigation />
|
||||
</Suspense>
|
||||
<main className="flex-1">{children}</main>
|
||||
</AuthModalProvider>
|
||||
</MessagesProvider>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import dynamic from "next/dynamic";
|
||||
import type { ReactNode } from "react";
|
||||
import { Suspense, type ReactNode } from "react";
|
||||
import MarketingNavigation from "../components/navigation/MarketingNavigation";
|
||||
import { MessagesProvider } from "../contexts/MessagesContext";
|
||||
import { AuthModalProvider } from "../contexts/AuthModalContext";
|
||||
@@ -19,7 +19,14 @@ export default function MarketingLayout({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<MessagesProvider messages={marketingMessages}>
|
||||
<AuthModalProvider>
|
||||
<MarketingNavigation />
|
||||
{/*
|
||||
* MarketingNavigation reads `usePathname()` to decide chromeless paths
|
||||
* (uncached data under `cacheComponents`). Suspense lets the static
|
||||
* shell prerender; the nav streams in with the correct visibility.
|
||||
*/}
|
||||
<Suspense fallback={null}>
|
||||
<MarketingNavigation />
|
||||
</Suspense>
|
||||
<main className="flex-1">{children}</main>
|
||||
<Footer />
|
||||
</AuthModalProvider>
|
||||
|
||||
Reference in New Issue
Block a user