I have a theme switch toggle on the top AppBar which is a client component.
The main layout is SSR and uses the nextjs App router. It has theme settings <ThemeProvider theme={lightOrDarkTheme}>
. Prior to App router/SSR I was able to use the cookie I set in the TopAppBar component to affect the theme change in layout file. With SSR, the cookie which is set and I can see in the browser is not accessible by server. Cookie is on the client side, the layout.jsx file cannot read the cookie and hence the theme toggle does not work.
I would appreciate tips on how to achieve this.
- I do not want to ‘use client’ at a top level such as
layout.jsx
as it defeats the purpose of SSR. - I also do not want to change TopAppBar to
use server
as it has way too much client code such as useEffect, mui styles …
Here is layout.jsx
import {lightTheme, darkTheme} from '@/components/theme';
import TopAppBar from '@/components/ui/topAppBar';
import { cookies } from 'next/headers';
const cookieStore = cookies();
export default function RootLayout({
children,
}) {
const cookieDark = cookieStore.get('darkTheme').value;
const theme = cookieDark=="true"? darkTheme: lightTheme;
....
<ThemeProvider theme={theme}>
And here is TopAppBar code:
'use client'
...
export default function TopAppBar() {
...
const handleThemeChange = () => {
setCookie('darkTheme',cookies.darkTheme == "true"? false: true, { path: '/' });
setDarkState(cookies.darkTheme == "true"? false: true);
};
Edit: Adding screenshot showing that cookie value is always false on cookies from next/header. Left: Browser (Client) and Right (Server console)
2
Answers
Hope this will be useful for someone else. Seems to be a bug in nextJs?
This strangely does not work (This is the way shown the next js docs)
However, if you directly use
cookies.get()
, it worksyou can.
you can access cookies from server side, nextJs have a function for this.
reference : https://nextjs.org/docs/app/api-reference/functions/cookies.