@anshumanb, certainly!
Here’s what I tried:
User logs in → Server action is triggered → Returns success message → Trigger a refresh (here it breaks)
The data seems fine in all server components, they instantly get updated but the header client component doesn’t
Client side header component:
export default function HeaderAuth() {
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
const router = useRouter()
const supabase = createClient(); // client side
useEffect(() => {
const checkSession = async () => {
const { data: { session } } = await supabase.auth.getSession();
console.log("Initial session check:", session); // Debug log
setUser(session?.user ?? null);
setLoading(false);
};
const { data: { subscription } } = supabase.auth.onAuthStateChange((event, session) => {
console.log("Auth state changed:", event, session); // Debug log
setUser(session?.user ?? null);
setLoading(false);
});
checkSession();
return () => {
subscription.unsubscribe();
};
}, []);
const handleLogout = async () => {
const result = await logout()
if (result.success) {
setUser(null)
router.push("/")
router.refresh()
} else {
console.error("Logout failed:", result.error)
}
}
return (
<div>
{user ? (
<div>
<span>Hello, {user.email}!</span>
<button onClick={handleLogout}>Logout</button>
</div>
) : (
<Link href="/login">
<LogInIcon className="mr-2" /> Log in
</Link>
)}
</div>
)
}
Login action (server side)
export async function login(prevState: { error: string | null; success: boolean }, formData: FormData) {
const supabase = await createClient()
// type-casting here for convenience
// in practice, you should validate your inputs
const data = {
email: formData.get('email') as string,
password: formData.get('password') as string,
}
const { error } = await supabase.auth.signInWithPassword(data)
if (error) {
return { error: error.message, success: false }
}
revalidatePath('/', 'layout')
return { error: null, success: true }
}
Login page (client side)
"use client"
import { useActionState, useEffect } from 'react'
import { login, signup } from './actions'
import { useRouter } from 'next/navigation'
export default function LoginPage() {
const [state, formAction, isPending] = useActionState(login, { error: null, success: false })
const router = useRouter()
useEffect(() => {
if (state?.success) {
router.push("/private")
router.refresh();
}
}, [state, router])
return (
<form action={formAction}>
<label htmlFor="email">Email:</label>
<input id="email" name="email" type="email" required />
<label htmlFor="password">Password:</label>
<input id="password" name="password" type="password" required />
<button>Log in</button>
{/* <button formAction={signup}>Sign up</button> */}
{state?.error && <p className="error">{state.error}</p>}
{isPending && <p>Please wait...</p>}
</form>
)
}