Kal
Kal

Reputation: 1774

How can action on clientside dispatch action on serverside?

I have a theme switch toggle on the top AppBar which is a client component.

enter image description here

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.

enter image description here

I would appreciate tips on how to achieve this.

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) enter image description here

Upvotes: 0

Views: 131

Answers (2)

Kal
Kal

Reputation: 1774

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)

import { cookies } from 'next/headers';
const cookieStore = cookies();

    export default function RootLayout({
      ...
        
        const cookieDark = cookieStore.get('darkTheme'); //This does not synch when cookies on browser changes

However, if you directly use cookies.get(), it works

import { cookies } from 'next/headers';

export default function RootLayout({
   ...
    const cookieDark = cookies().get('darkTheme'); //This synchs when cookies on browser changes

Upvotes: 0

David
David

Reputation: 20

the layout.jsx file cannot read the cookie and hence the theme toggle does not work.

you can.

you can access cookies from server side, nextJs have a function for this.

reference : https://nextjs.org/docs/app/api-reference/functions/cookies.

Upvotes: -1

Related Questions