Next.js Discord

Discord Forum

Calling a Client Component is causing compiler issues

Answered
Broken Nokia posted this in #help-forum
Open in Discord
Avatar
Here is the console error log since i'm having issues uploading an image of the console:

 ○ Compiling / ...
 ⨯ ./src/utils/supabase/server.ts
Error:
  × You're importing a component that needs next/headers. That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/getting-started/
  │ react-essentials#server-components
  │
  │
   ╭─[D:\Workspaces\WebDev\zo-house-user-frontend\src\utils\supabase\server.ts:1:1]
 1 │ import { createServerClient, type CookieOptions } from "@supabase/ssr";
 2 │ import { cookies } from "next/headers";
   · ───────────────────────────────────────
 3 │
 4 │ export function createClient() {
 4 │     const cookieStore = cookies();
   ╰────

Import trace for requested module:
./src/utils/supabase/server.ts
./src/app/page.tsx
./src/app/cart-total.tsx


I am using Supabase Auth, that's where I'm calling the cookies() function.

The root page.tsx file includes the Cart-Total component at the bottom which is a client component. This error goes away when I comment on this component.

I don't understand what is causing this issue since calling a client-rendered component in a page that is rendered on the server is allowed.

It also mentions that server components are not supported by the pages router when I'm using the app router. This could just be extra information and not necessarily the compiler thinking I'm using the pages router.

I've been racking my brains unable to understand this. Any help is greatly appreciated.
Answered by Broken Nokia
a server component cannot export anything apart from functions
Image
View full answer

48 Replies

Avatar
Here's the server.ts file being referred to in the error:

import { createServerClient, type CookieOptions } from "@supabase/ssr";
import { cookies } from "next/headers";

export function createClient() {
    const cookieStore = cookies();

    return createServerClient(
        process.env.NEXT_PUBLIC_SUPABASE_URL!,
        process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
        {
            cookies: {
                getAll() {
                    return cookieStore.getAll();
                },
                setAll(cookiesToSet) {
                    try {
                        cookiesToSet.forEach(({ name, value, options }) =>
                            cookieStore.set(name, value, options)
                        );
                    } catch {
                        // The `setAll` method was called from a Server Component.
                        // This can be ignored if you have middleware refreshing
                        // user sessions.
                    }
                },
            },
        }
    );
}
Taken straight out of supabase docs for SSR
Avatar
Well, that's when you use a supabase instance in server component
I assume you followed this, right?
@Broken Nokia
see @Broken Nokia you are creating a server client
you imported createServerClient
there is another one called createBrowserClient
import { createBrowserClient } from '@supabase/ssr'

export function createClient() {
  return createBrowserClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
  )
}
Avatar
it's okay - you seems to be working on auth
check the step 3, you have a tab to switch client/server
Avatar
Correct, I copied the code as is
Avatar
@Broken Nokia
Image
before you copy the code, please take some time to read the doc
To access Supabase from your Next.js app, you need 2 types of Supabase clients:
Avatar
Yes, Ive got both of them in my project. There's a client.ts file exporting a function to create a browserClient and another server.ts file exporting a function for the serverClient
Avatar
yeah, so the issue is from using supabase server instance in your client component
Avatar
I'm using the server instance in the page.tsx file that is server rendered


Not in the client component. I'm not creating a supabase instance at all in the client component
I'm just calling the client component (Cart-Total component) inside my page.tsx file
Avatar
show me the whole code then
Avatar
Image
root page.tsx file 👆
CartTotal at the end is a client component
Avatar
show me <CardTotal />
aha, wait, are you using page directory?
Avatar
nope, using the app router
Avatar
but you are getting this error
You're importing a component that needs next/headers. That only works in a Server Component which is not supported in the pages/ directory.
show me <CardTotal /> !
Avatar
Image
Avatar
show me useCart and give me a screenshot of your directory structure
Avatar
Image
Image
i think i might have figured it out, give me a few mins to test it out and i'll let you know if i got it or not
yep, i got it
i was exporting a type and an array
Avatar
a server component cannot export anything apart from functions
Image
Answer
Avatar
did you export them from supabase/server.ts?
Avatar
nope
Avatar
oh I see
from page.tsx?
Avatar
yes
Avatar
and you used them in client component?
oh man
Avatar
and server components can only export functions

so the page.tsx file was not considered as a server component (even though it should be by default when there is no "use client" directive)
thank you for time regardless, i appreciate you helping me debug this issue
have a great day/night
Avatar
yr welcome!