From 3d5e9e36d6b48bb6289510edb1461c3c82358216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=BCger?= Date: Sun, 23 Nov 2025 20:27:44 +0100 Subject: [PATCH] fix: resolve ThemeProvider SSR issue causing 500 error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The app was crashing with "useTheme must be used within ThemeProvider" error during server-side rendering. Changes: - Created AppLayout client component to wrap Navbar - Modified useTheme hook to return default values during SSR instead of throwing an error - Updated Navbar to safely handle theme context - Moved Navbar rendering into client-side only AppLayout This fixes the SSR hydration mismatch and allows the app to render correctly on both server and client. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- app/layout.tsx | 5 ++--- components/layout/AppLayout.tsx | 13 +++++++++++++ components/layout/Navbar.tsx | 10 ++++++---- components/providers/ThemeProvider.tsx | 7 ++++++- 4 files changed, 27 insertions(+), 8 deletions(-) create mode 100644 components/layout/AppLayout.tsx diff --git a/app/layout.tsx b/app/layout.tsx index b482475..827d9f6 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -2,7 +2,7 @@ import type { Metadata } from 'next'; import { Inter } from 'next/font/google'; import './globals.css'; import { Providers } from '@/components/providers/Providers'; -import { Navbar } from '@/components/layout/Navbar'; +import { AppLayout } from '@/components/layout/AppLayout'; const inter = Inter({ subsets: ['latin'], @@ -44,8 +44,7 @@ export default function RootLayout({ - -
{children}
+ {children}
diff --git a/components/layout/AppLayout.tsx b/components/layout/AppLayout.tsx new file mode 100644 index 0000000..45bc091 --- /dev/null +++ b/components/layout/AppLayout.tsx @@ -0,0 +1,13 @@ +'use client'; + +import { ReactNode } from 'react'; +import { Navbar } from './Navbar'; + +export function AppLayout({ children }: { children: ReactNode }) { + return ( +
+ +
{children}
+
+ ); +} diff --git a/components/layout/Navbar.tsx b/components/layout/Navbar.tsx index 22e710e..18468d1 100644 --- a/components/layout/Navbar.tsx +++ b/components/layout/Navbar.tsx @@ -19,14 +19,16 @@ const navItems = [ export function Navbar() { const pathname = usePathname(); const [mounted, setMounted] = useState(false); - const { theme, setTheme, resolvedTheme } = useTheme(); + const themeContext = useTheme(); useEffect(() => { setMounted(true); }, []); const toggleTheme = () => { - setTheme(resolvedTheme === 'dark' ? 'light' : 'dark'); + if (themeContext) { + themeContext.setTheme(themeContext.resolvedTheme === 'dark' ? 'light' : 'dark'); + } }; return ( @@ -59,14 +61,14 @@ export function Navbar() { {/* Theme Toggle */} - {mounted && ( + {mounted && themeContext && (