Next.js Discord

Discord Forum

Passing data from layout to any child component

Unanswered
<Milind ツ /> posted this in #help-forum
Open in Discord
Is there a way to pass down any data from layout file to child components? For instance, i am using route groups so they have a common layout file that checks up if the user session is available and if session is available and user is present in the database, i want to pass this user object to any child pages under this layout. How can i achieve this behaviour? I am thinking of using context but lemme know of various ways to do this.

Currently, i have to check this session and user on each page which is troublesome.

My layout content code is like this:

const SideContent = async ({ children }: PropsWithChildren) => {
   const session = await getServerSession(authOptions);

   if (session == null || session.user == null || session.user.email == null) {
      return (
         <>
         </>
      );
   }
   const response = await findUserByEmail(session.user.email);
   if (typeof response == "string") {
      return (
         <>
         </>
      );
   }
   if (response.status == 403) {
      return (
         <>
         </>
      );
   }

   return (
      <>
         <section className="mx-3 flex min-h-screen w-full flex-col rounded-lg py-4 sm:mx-6">
            <AppBreadcrumb />

            {children}
         </section>
      </>
   );
};

export default SideContent;

31 Replies

Cimarrón Uruguayo
just make a context and wrap it
But since this sidecontent is a server component, how can i update the context from within this component, since we dont import any child component directly here. (i could do it in breadcrumb component)

but i also want to access user object from server component without checking for session again
Cimarrón Uruguayo
I don't have much experience with next best practises, but i think layout.tsx should only be containing common ui for its route
rest can be done in children
did you try doing it in the breadcrumb component
yea i can do it here since its a client component. But on each page in the route group, i have to mark them as client to be able to use this context user.
Cimarrón Uruguayo
hmm what about using middleware instead?
so you can have a middleware function that redirects to appropriate auth (register or login) page if user is not authenticated
so then you don't even have to worry about rendering server or client components
basically, i am building a ecommerce project so say on one page, i want to fetch user details, so i have to check for session first, then check if user exists and then get details.

so i thought of moving this session and user check to layout and passing down user object to each page. but if we are using context, then i have to mark each page as client. Then i cant run any server function on such page unless i create a separate component.(ig i could do that and use suspense 🧐 )
middleware check would be only for check if user is authorised or not.
Cimarrón Uruguayo
import { getServerSideUser } from "@/lib/get-user"

const Component: React.FC = async () => {
  const nextCookies = cookies()
  const { user } = await getServerSideUser(nextCookies)

  return <ChildComponent user={user} />
}
this is what I mean
depends on cookies
@Cimarrón Uruguayo tsx import { getServerSideUser } from "@/lib/get-user" const Component: React.FC = async () => { const nextCookies = cookies() const { user } = await getServerSideUser(nextCookies) return <ChildComponent user={user} /> }
yea this is what i am already doing. But i have like 10+ pages so it checks for this user on each page.

const layout = () => {
   return (
      <>
         <section>
            sidebar
            sidecontent
         </section>
      </>
   )
}


so each page that comes under sidecontent, say /dashboard/payments, i have to pass down the user object.
Cimarrón Uruguayo
i see the problem now
unless its not a bad practice to check on each page, then its fine. But it would not be good for database call
Cimarrón Uruguayo
yeah I was going to suggest cache
making a "context" would be more elegant tho
and make it revalidate
when auth status changes
@Cimarrón Uruguayo when auth status changes
Palomino
This cache only lasts for the one request so other requests won't have the some cache
hmm

is there not a way where we can use context but still being able to use this context value in the server component pages so i could do like

const {user} = useUser();
Palomino
context only works on client components I believe
@Palomino If you are worried about the amount of redundant database calls, you can use `cache` https://nextjs.org/docs/app/building-your-application/caching#react-cache-function
weird behaviour, while trying to use this cache with prisma db call, it wont let u call the function in server components
Palomino
That's weird, cache is meant to work with server components
It throws likegetUser is not a function