Passing serializable object from serverside component to clientside with NextJS

27 views Asked by At

My NextJS app is using a gRPC client to fetch data for a given user. I am trying to pass that response from a server side component to a client side component using serialization. However, the returned response uses a class therefore I am getting the error: Error: Only plain objects, and a few built-ins, can be passed to Client Components from Server Components. Classes or null prototypes are not supported.

In order to bypass this, I am using lodash's toPlainObject() method on the response. However, that is not working. Does anyone know why? I've confirmed the transformed object is a plain object by using lodash's isPlainObject() method, however the error still persists.

To zoom out one level in case this isn't the right approach in general, my main goals are to:

  1. Do the authentication token exchange needed to configure the gRPC client on the server to keep it secure
  2. Fetch data using the gRPC client in whatever component it may be needed in, server or client side

Thanks!

async function getUserData() {
    const client = await getClient();

    const userRequest = GetUserRequest.create();
    if (client) {
      try {
          const userResponse = await client.getUser(userRequest);
          return userResponse.response.user;
      } catch (error) {
        console.log("Failed to fetch user data.");
      }
    }
  }

export default async function HeaderLayout({
  children,
}: {
  children: ReactNode;
}) {
  const userData = await getUserData();
  console.log(isPlainObject(userData)); // return false because its a class still
  const user = userData ? toPlainObject(userData) : undefined;
  console.log(isPlainObject(user)); // returns true because its a plain object

  return (
     <html lang="en">
      <body>
        <AppRouterCacheProvider>
            <Box
              sx={{
                display: "flex",
                overflowX: "scroll",
              }}
            >
              <SideNav />
              <Box
                sx={{ display: "flex", flexDirection: "column", flexGrow: 1 }}
              >
                <Header user={user}/> //Errors here when passing the prop
                <Content main>{children} </Content>
              </Box>
            </Box>
        </AppRouterCacheProvider>
      </body>
    </html>
  );
}
0

There are 0 answers