From d504866aad85f0b125a2c363a501bee002b9f8cf Mon Sep 17 00:00:00 2001 From: charlesgauthereau Date: Tue, 23 Dec 2025 09:06:06 +0100 Subject: [PATCH] Patching hydratation error due to theme. --- app/(customer)/dashboard/layout.tsx | 2 + app/layout.tsx | 8 +-- app/providers.tsx | 18 +++--- src/features/browser/theme-meta-updater.tsx | 66 ++++++--------------- 4 files changed, 30 insertions(+), 64 deletions(-) diff --git a/app/(customer)/dashboard/layout.tsx b/app/(customer)/dashboard/layout.tsx index 4f67f80f..3e683bd0 100644 --- a/app/(customer)/dashboard/layout.tsx +++ b/app/(customer)/dashboard/layout.tsx @@ -5,6 +5,7 @@ import {SidebarInset, SidebarProvider} from "@/components/ui/sidebar"; import {AppSidebar} from "@/components/wrappers/dashboard/common/sidebar/app-sidebar"; import {Header} from "@/features/layout/Header"; import {currentUser} from "@/lib/auth/current-user"; +import {ThemeMetaUpdater} from "@/features/browser/theme-meta-updater"; export default async function Layout({children}: { children: ReactNode }) { const user = await currentUser(); @@ -13,6 +14,7 @@ export default async function Layout({children}: { children: ReactNode }) { return (
+
diff --git a/app/layout.tsx b/app/layout.tsx index c4e12adc..a9b718c3 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -5,7 +5,6 @@ import {Providers} from "./providers"; import {cn} from "@/lib/utils"; import {ConsoleSilencer} from "@/components/wrappers/common/console-silencer"; import {inter} from "@/fonts/fonts"; -import {currentUser} from "@/lib/auth/current-user"; const title = process.env.PROJECT_NAME ?? "App Title"; @@ -23,9 +22,6 @@ export default async function RootLayout({ children: React.ReactNode; }>) { - const user = await currentUser(); - console.info("useerrrrr",user) - return ( @@ -33,7 +29,9 @@ export default async function RootLayout({ - {children} + + {children} + ); diff --git a/app/providers.tsx b/app/providers.tsx index 9adc7a45..7bb5f6d5 100644 --- a/app/providers.tsx +++ b/app/providers.tsx @@ -1,27 +1,25 @@ "use client"; -import { PropsWithChildren, Suspense } from "react"; -import { ThemeProvider } from "@/features/theme/theme-provider"; +import {PropsWithChildren, Suspense} from "react"; +import {ThemeProvider} from "@/features/theme/theme-provider"; -import { Toaster } from "@/components/ui/sonner"; -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import {ThemeMetaUpdater} from "@/features/browser/theme-meta-updater"; +import {Toaster} from "@/components/ui/sonner"; +import {QueryClient, QueryClientProvider} from "@tanstack/react-query"; -export type ProviderProps = PropsWithChildren<{ -}>; + +export type ProviderProps = PropsWithChildren<{}>; const queryClient = new QueryClient(); export const Providers = (props: ProviderProps) => { return ( - + - - + {props.children} diff --git a/src/features/browser/theme-meta-updater.tsx b/src/features/browser/theme-meta-updater.tsx index 826aaf59..f7ef3a62 100644 --- a/src/features/browser/theme-meta-updater.tsx +++ b/src/features/browser/theme-meta-updater.tsx @@ -1,67 +1,35 @@ "use client"; import {useTheme} from "next-themes"; -import {useEffect} from "react"; +import {useEffect, useState} from "react"; import {authClient} from "@/lib/auth/auth-client"; export function ThemeMetaUpdater() { - const {resolvedTheme, setTheme} = useTheme(); - const {data: session} = authClient.useSession(); + const {setTheme, resolvedTheme} = useTheme(); + const {data: session, isPending} = authClient.useSession(); + const [mounted, setMounted] = useState(false); useEffect(() => { - if (!resolvedTheme) return; + setMounted(true); + }, []); + + useEffect(() => { + if (isPending || !session?.user?.theme) return; + setTheme(session.user.theme); + }, [session, isPending, setTheme]); + + useEffect(() => { + if (!mounted || !resolvedTheme) return; const color = resolvedTheme === "dark" ? "#000000" : "#ffffff"; - let tag = document.querySelector('meta[name="theme-color"]'); if (!tag) { tag = document.createElement("meta"); - tag.setAttribute("name", "theme-color"); + tag.name = "theme-color"; document.head.appendChild(tag); } - tag.setAttribute("content", color); - }, [resolvedTheme]); - - useEffect(() => { - if (!session?.user?.theme) return; - setTheme(session.user.theme); - }, [session, resolvedTheme, setTheme]); - + tag.content = color; + }, [mounted, resolvedTheme]); return null; } - -// -// "use client" -// import {useEffect, useState} from "react"; -// import {useTheme} from "next-themes"; -// import {authClient} from "@/lib/auth/auth-client"; -// -// export function ThemeMetaUpdater() { -// const [mounted, setMounted] = useState(false); -// const {resolvedTheme, setTheme} = useTheme(); -// const {data: session} = authClient.useSession(); -// -// useEffect(() => setMounted(true), []); -// -// useEffect(() => { -// if (!mounted || !resolvedTheme) return; -// const color = resolvedTheme === "dark" ? "#000000" : "#ffffff"; -// let tag = document.querySelector('meta[name="theme-color"]'); -// if (!tag) { -// tag = document.createElement("meta"); -// tag.setAttribute("name", "theme-color"); -// document.head.appendChild(tag); -// } -// tag.setAttribute("content", color); -// }, [mounted, resolvedTheme]); -// -// useEffect(() => { -// if (!mounted || !session?.user?.theme) return; -// if (resolvedTheme !== session.user.theme) { -// setTheme(session.user.theme); -// } -// }, [mounted, session, setTheme]); -// -// return null; -// }