diff --git a/js/web/src/routes/__root.tsx b/js/web/src/routes/__root.tsx index bf569b7f6..ca7a4d11a 100644 --- a/js/web/src/routes/__root.tsx +++ b/js/web/src/routes/__root.tsx @@ -19,6 +19,14 @@ import i18next from "../lib/i18n"; /** Routes that should render without sidebar/header chrome. */ const POPOUT_PREFIXES = ["/chat-popout/", "/embed/"]; +/** Routes that own their own chrome via a layout route + * (see routes/dashboard/route.tsx). The root only needs to know about + * these to decide whether to wrap with ChromeLayout or render the + * Outlet bare. The dashboard's provider tree is mounted by the layout + * route itself, not by this check, so a stale read here is just a + * visual flash — not a render race. */ +const DASHBOARD_PREFIX = "/dashboard"; + export const Route = createRootRoute({ component: RootLayout, pendingComponent: RouteLoadingSkeleton, @@ -80,13 +88,12 @@ function RouteLoadingSkeleton() { function RootLayout() { // Popout routes (chat popout, embeds) skip the regular chrome and - // render their own minimal layout. Everything else gets the full - // provider tree; the chrome decision (regular vs dashboard) is now - // owned by route layouts — see routes/dashboard/route.tsx for the - // dashboard chrome layout, and the non-dashboard routes get the - // regular chrome via ChromeLayout below. The root no longer switches - // chrome based on pathname, which closed a render race where the - // dashboard route was mounted without its DashboardStoreContext. + // render their own minimal layout. Dashboard routes also skip the + // regular chrome — they own their own via routes/dashboard/route.tsx. + // The dashboard layout route mounts DashboardChrome (with its + // DashboardStoreContext etc.) before its children, so the chrome + // decision here is purely visual; a stale read just causes a brief + // flash, not a render race. const pathname = useRouterState({ select: (s) => s.resolvedLocation?.pathname ?? "", }); @@ -111,6 +118,22 @@ function RootLayout() { ); } + const isDashboard = + actualPathname === DASHBOARD_PREFIX || + actualPathname.startsWith(`${DASHBOARD_PREFIX}/`); + + if (isDashboard) { + return ( + + + + + + + + ); + } + return (