Next.js Discord

Discord Forum

Handling Shared Values between Client and Server in Next.js

Unanswered
Orinoco Crocodile posted this in #help-forum
Open in Discord
Orinoco CrocodileOP
Hello everyone, how's it going? I'm just getting started with Next.js 13 and have a question regarding storing a value that will be used throughout the entire application. I know I can use solutions like the context API, but that seems to work only for client-side components and not for the server. It wouldn't be a problem for me to have this information in two variables, one for client-side components and another for the server, but my dilemma is figuring out how to handle this on the server side itself. If anyone has any ideas on how this can be done, I'd greatly appreciate it.:noice:

27 Replies

Toyger
you can use cookies
@Orinoco Crocodile cache is the equivalent for RSCs: https://prismic.io/blog/advanced-nextjs-server-context
- craft a function that gets the data
- pass the data to a context for client components
- call the function directly in RSCs
the key is to use the "cache" function => this way your data is deduplicated for each request, similarly to having one shared context for all RSCs
If you value happens to change a lot upon users interaction you can use cookies, as stated by @Toyger
Orinoco CrocodileOP
Great, thank you, everyone! Using cookies seems to be the easiest solution, but I've run into a problem. I have a file used for making requests, and it's called for both client-side components and the server. In one part of the file, I do the following:
const componentType = typeof window === 'undefined' ? 'server' : 'client';
if (componentType === 'server') {
  cookiesServer().setCookie('newCookie');
}

In another file:
import { cookies } from 'next/headers';

export function cookiesServer() {
  async function setCookie(cookie: string) {
    'use server';
    cookies().set('cookie1', cookie);
  }

  return {
    setCookie
  };
}

Doing this causes the following error:
You're importing a component that needs next/headers. That only works in a Server Component but one of its parents is marked with 'use client', so it's a Client Component.

Perhaps the check componentType === 'server' isn't working as I would like. Any suggestions on resolving this issue would be greatly appreciated.
like, have a component that takes the value you want
as a prop
basically you'd want to use the server value to prerender your component, and then the client value in effects or similar
for setting cookie in particular, you'd want to do this client-side
server-side, setting a cookie is done via the SET-COOKIE response header
usually we use it to setup HTTP only cookies that can't be set with client-side JS
like auth tokens
if you don't need an HTTP cookie then you'll probably want to set the cookie client-side instead
but I don't know about the specifics of your app
Orinoco CrocodileOP
I believe that Cookies would already help me; however, I've noticed that to use functions like set() it's necessary to use server actions. I'm trying to do this in a clean project initialized with the latest version of Next.js, but I'm encountering the error on the image. Seeing the documentation, it seems that just adding 'use server' to the function should be enough, but perhaps I might be overlooking something.

(its the same error in my real project, I just wanted to simplify)
implicitely your code is equivalent to setting the cookie from the RSC, it's like you didn't use the server action at all
if your cookie is not HTTP-only, you could set the cookie from the client
'useEffect(() => { set your cookie here from client }, []'
if it is HTTP-only, you may call your action
'useEffect(() => { call your server action here }, [])'
Orinoco CrocodileOP
huuum ok, my goal with this is exactly to save a session code, which I receive on the first request I make, and then I have to use the same code for the subsequent ones. I have no idea where to save this information.

const API_URL = process.env.NEXT_PUBLIC_API_URL;

export default async function post(endpoint: string, data?: any, cache: RequestCache = 'no-store') {
  let headers: { [key: string]: string } = {
    'Content-Type': 'application/json'
  };

  // if has session hash in cookies, send it to api
  headers = {
    ...headers,
    'session-hash': 'get session hash from cookies'
  };

  const res = await fetch(`${API_URL}/${endpoint}`, {
    cache: cache,
    method: 'POST',
    body: JSON.stringify(data),
    headers: headers,
    credentials: 'include'
  });


  const newSessionToken = res.headers.get('session-hash');

  // set newSessionToken to cookies

  // rest of the code
}