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.
#Handling Shared Values between Client and Server in Next.js
28 messages · Page 1 of 1 (latest)
🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord
🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in id:customize
✅ You can mark a message as the answer for your post with Right click -> Apps -> Mark Solution
(if you don't see the option, try refreshing Discord with Ctrl + R)
you can use cookies
@lucid stratus 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 @lucid ether
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.
you'd want to split the code to separate the client and server version
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
A bit like what I call relaying when fetching data: https://ericbureltech.hashnode.dev/how-to-setup-client-server-relaying-in-nextjs
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
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)
It is just a normal function when the function execute directly in the page component.
A server action need to be used with form, event handler or useEffect and It will make a POST request to that route
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 }, [])'