SupabaseS
Supabase11mo ago
enszrlu

Best way to get authenticated user on client side

Hi all,

Trying to understand what is the best way to access authenticated user in my app. (using nextjs 15 and supabase) in client components.
I thought having a context would be a good idea, but I could not get "onAuthStateChange" to work properly. My context works initially but does not update between logins.

What is the best way to access current user in client components?

Option 1: Getting the user in a useEffect and updating local state?
const { data: { user } } = await supabase.auth.getUser()


Option 2: Having a context and wrapping the app with it so all client components can access it.
'use client';

import { createClient } from '@/utils/supabase/client';
import { User } from '@supabase/supabase-js';
import React, { createContext, useContext, useEffect, useState } from 'react';

type UserContextType = {
  user: User | null;
  loading: boolean;
};

const UserContext = createContext<UserContextType | undefined>(undefined);

export const UserProvider: React.FC<{ children: React.ReactNode }> = ({
  children
}) => {
  const supabase = createClient();
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchUser = async () => {
      setLoading(true);
      const { data: user } = await supabase.auth.getUser();
      setUser(user.user);
      setLoading(false);
    };

    fetchUser();

    // Listen for auth state changes
    const { data: subscription } = supabase.auth.onAuthStateChange(() =>
      fetchUser()
    );

    return () => subscription?.subscription.unsubscribe();
  }, []);

  return (
    <UserContext.Provider value={{ user, loading }}>
      {children}
    </UserContext.Provider>
  );
};

export const useGetCurrentUser = () => {
  const context = useContext(UserContext);
  if (!context) throw new Error('useUser must be used within a UserProvider');
  return context;
};
Was this page helpful?