createContext requires 'use client';, but supabase requires 'use server';
Unanswered
Northern snakehead posted this in #help-forum
Northern snakeheadOP
I'm trying to make a
sessionContext.tsx:
createContext only works on client components, but the
sessionContext
, which listens to auth events. sessionContext.tsx:
"use client";
import * as React from "react";
import { createClient } from "@/utils/supabase/server";
import { Session } from "@supabase/supabase-js";
// First a session context has to be created to listen to the auth changes, ref - https://supabase.com/docs/reference/javascript/auth-onauthstatechange (use React context for the user session).
const SessionContext = React.createContext<Session | null>(null);
export const SessionProvider = ({
children,
}: {
children: React.ReactNode;
}) => {
const [session, setSession] = React.useState<Session | null>(null);
React.useEffect(() => {
const monitorAuthState = async () => {
const supabase = await createClient();
const {
data: { subscription },
} = supabase.auth.onAuthStateChange((event, session) => {
setSession(session);
});
return () => {
subscription?.unsubscribe();
};
};
monitorAuthState();
}, []);
return (
<SessionContext.Provider value={session}>
{children}
</SessionContext.Provider>
);
};
export const useSessionContext = () => {
const context = React.useContext(SessionContext);
return context;
};
createContext only works on client components, but the
monitorAuthState
func contains supabase
, which works only on server components. I tried to add "use server";
inside the same func, but it's showing an error. Can anyone kindly guide how to fix this?8 Replies
American black bear
you cannot use the supabase client in client components
to fix this create a server action that does the thing and and use it instead
American black bear
another thing is you should probably create a single
with this approach you will probably be able to do
supabase
client instance, export it, and use it throughout your application instead of creating a new connection every time you use supabase. with this approach you will probably be able to do
subscription
thing without the use of server actions or "use server" as you've mentioned@American black bear another thing is you should probably create a single `supabase` client instance, export it, and use it throughout your application instead of creating a new connection every time you use supabase.
with this approach you will probably be able to do `subscription` thing without the use of server actions or "use server" as you've mentioned
Northern snakeheadOP
Yes, I've created the -
Also, in the
I just wanted to ask that, should I use this func in the SessionContext(which is shared above)?
server.ts
, client.ts
and middleware.ts
files for supabase instance and exported them.Also, in the
auth.ts
, I've used the - "use serve";
, and created a func named - monitorAuthState()
:export async function monitorAuthState() {
const supabase = await createClient();
const {
data: { subscription },
} = supabase.auth.onAuthStateChange((event, session) => {
if (event === "SIGNED_IN") {
return session;
} else if (event === "SIGNED_OUT") {
return null;
}
});
return () => {
subscription?.unsubscribe();
};
}
I just wanted to ask that, should I use this func in the SessionContext(which is shared above)?
I'm getting an err in here, just trying to debug this:
on line -
Argument of type '(event: AuthChangeEvent, session: Session | null) => Session | null | undefined' is not assignable to parameter of type '(event: AuthChangeEvent, session: Session | null) => void | Promise<void>'.
Type 'Session | null | undefined' is not assignable to type 'void | Promise<void>'.
Type 'null' is not assignable to type 'void | Promise<void>'.ts(2345)
(parameter) session: Session | null
on line -
supabase.auth.onAuthStateChange((event, session) => {
@American black bear you cannot use the supabase client in client components
Northern snakeheadOP
Hey, I got this working!
I now imported supabase from client.ts and used it like this:
Now, it's working fine 👍
Thanks
I now imported supabase from client.ts and used it like this:
"use client";
import * as React from "react";
import { Session } from "@supabase/supabase-js";
import { createClient } from "@/utils/supabase/client";
// First a session context has to be created to listen to the auth changes, ref - https://supabase.com/docs/reference/javascript/auth-onauthstatechange (use React context for the user session).
const SessionContext = React.createContext<Session | null>(null);
export const SessionProvider = ({
children,
}: {
children: React.ReactNode;
}) => {
const [session, setSession] = React.useState<Session | null>(null);
React.useEffect(() => {
const supabase = createClient();
const fetchSession = async () => {
const { data } = await supabase.auth.getSession();
setSession(data.session);
};
fetchSession(); // Call the function
const { data: authListener } = supabase.auth.onAuthStateChange((_event, session) => {
setSession(session);
});
return () => {
authListener?.subscription?.unsubscribe();
};
}, []);
return (
<SessionContext.Provider value={session}>
{children}
</SessionContext.Provider>
);
};
export const useSessionContext = () => {
const context = React.useContext(SessionContext);
return context;
};
Now, it's working fine 👍
Thanks
Original message was deleted
Northern snakeheadOP
Hi, thank you so much for the reference. I've updated my
Thanks 🙂
server
and client
according to this, it's working perfectly fine. Currently, working on the AuthProvider setup which you just sent.Thanks 🙂