@@ -3,6 +3,7 @@ import * as Sentry from "@sentry/react-router";
33import Script from "next/script" ;
44import { Links , Meta , Outlet , Scripts } from "react-router" ;
55import type { LinksFunction } from "react-router" ;
6+ import { ThemeProvider , useTheme } from "next-themes" ;
67// plane imports
78import { SITE_DESCRIPTION , SITE_NAME } from "@plane/constants" ;
89import { cn } from "@plane/utils" ;
@@ -14,9 +15,10 @@ import faviconIco from "@/app/assets/favicon/favicon.ico?url";
1415import icon180 from "@/app/assets/icons/icon-180x180.png?url" ;
1516import icon512 from "@/app/assets/icons/icon-512x512.png?url" ;
1617import ogImage from "@/app/assets/og-image.png?url" ;
17- import { LogoSpinner } from "@/components/common/logo-spinner" ;
1818import globalStyles from "@/styles/globals.css?url" ;
1919import type { Route } from "./+types/root" ;
20+ // components
21+ import { LogoSpinner } from "@/components/common/logo-spinner" ;
2022// local
2123import { CustomErrorComponent } from "./error" ;
2224import { AppProvider } from "./provider" ;
@@ -51,7 +53,7 @@ export function Layout({ children }: { children: ReactNode }) {
5153 const isSessionRecorderEnabled = parseInt ( process . env . VITE_ENABLE_SESSION_RECORDER || "0" ) ;
5254
5355 return (
54- < html lang = "en" >
56+ < html lang = "en" suppressHydrationWarning >
5557 < head >
5658 < meta charSet = "utf-8" />
5759 < meta name = "viewport" content = "width=device-width, initial-scale=1" />
@@ -66,16 +68,12 @@ export function Layout({ children }: { children: ReactNode }) {
6668 < Meta />
6769 < Links />
6870 </ head >
69- < body >
71+ < body suppressHydrationWarning >
7072 < div id = "context-menu-portal" />
7173 < div id = "editor-portal" />
72- < AppProvider >
73- < div
74- className = { cn ( "h-screen w-full overflow-hidden bg-canvas relative flex flex-col" , "desktop-app-container" ) }
75- >
76- < main className = "w-full h-full overflow-hidden relative" > { children } </ main >
77- </ div >
78- </ AppProvider >
74+ < ThemeProvider themes = { [ "light" , "dark" , "light-contrast" , "dark-contrast" , "custom" ] } defaultTheme = "system" >
75+ { children }
76+ </ ThemeProvider >
7977 < Scripts />
8078 { ! ! isSessionRecorderEnabled && process . env . VITE_SESSION_RECORDER_KEY && (
8179 < Script id = "clarity-tracking" >
@@ -118,12 +116,25 @@ export const meta: Route.MetaFunction = () => [
118116] ;
119117
120118export default function Root ( ) {
121- return < Outlet /> ;
119+ return (
120+ < AppProvider >
121+ < div className = { cn ( "h-screen w-full overflow-hidden bg-canvas relative flex flex-col" , "desktop-app-container" ) } >
122+ < main className = "w-full h-full overflow-hidden relative" >
123+ < Outlet />
124+ </ main >
125+ </ div >
126+ </ AppProvider >
127+ ) ;
122128}
123129
124130export function HydrateFallback ( ) {
131+ const { resolvedTheme } = useTheme ( ) ;
132+
133+ // if we are on the server or the theme is not resolved, return an empty div
134+ if ( typeof window === "undefined" || resolvedTheme === undefined ) return < div /> ;
135+
125136 return (
126- < div className = "relative flex h-screen w-full items-center justify-center" >
137+ < div className = "relative flex bg-canvas h-screen w-full items-center justify-center" >
127138 < LogoSpinner />
128139 </ div >
129140 ) ;
0 commit comments