When I click the signin/signup link in email and get redirected to the app, I miss the page I made to welcome new users and gather more info for their profile because there's a moment where useUser() says it's no longer loading, but it doesn't provide a user object to my page.
In this demo all users will land on the welcome page regardless of whether or not they are new. I added http://localhost:3000/welcome as an Additional Redirect URL in Supabase and I pass { redirectTo: 'http://localhost:3000/welcome' } to supabaseClient.auth.signIn() which seems to have worked out, even for magic emails.
I've created a barebones pages/welcome.tsx file just to see what the values / steps are for useUser():
true null undefined
[Fast Refresh] rebuilding
false null undefined
SIGNED_IN {...object with access_token, user, etc...}
SIGNED_IN {...object with access_token, user, etc...}
true null undefined
// The SIGNED_IN/object about four more times
true null undefined
true {...object with id, aud, email, etc...} undefined
false {...object with id, aud, email, etc...} undefined
So as you can imagine, that one instant where it stops loading but user is still null pushes me back to /signin. But onAuthStateChange() knew there was a valid user even before useUser() returned null two more times!
My pages/signin.tsx has a similar check for user, where if it finds one it calls router.replace('/') to send the user back to the homepage. This whole process flickers by in an instant and a new user would miss my welcome page entirely.
It appears as though that false null print happens exactly when #access_token=... is removed from the URL (I screen recorded so I could move frame-by-frame through the redirects).
Returning to /welcome and refreshing prints the following to the console:
With no redirect to /signin, so it's definitely just when arriving fresh from the email link. However, it's probably notable that the user object has null for confirmed_at and created_at or any other date values, and userDetails remains undefined the whole time in both page load scenarios.
As a temporary fix, I've started storing the session from onAuthStateChange() with useState(), watching that from the useEffect() and including it in the list of "and not"s before pushing the user to /signin but that feels like it should be unnecessary!
When I click the signin/signup link in email and get redirected to the app, I miss the page I made to welcome new users and gather more info for their profile because there's a moment where
useUser()
says it's no longer loading, but it doesn't provide a user object to my page.In this demo all users will land on the welcome page regardless of whether or not they are new. I added
http://localhost:3000/welcome
as an Additional Redirect URL in Supabase and I pass{ redirectTo: 'http://localhost:3000/welcome' }
tosupabaseClient.auth.signIn()
which seems to have worked out, even for magic emails.I've created a barebones
pages/welcome.tsx
file just to see what the values / steps are foruseUser()
:And here's what prints to the console:
So as you can imagine, that one instant where it stops loading but
user
is stillnull
pushes me back to /signin. ButonAuthStateChange()
knew there was a valid user even beforeuseUser()
returnednull
two more times!My
pages/signin.tsx
has a similar check for user, where if it finds one it callsrouter.replace('/')
to send the user back to the homepage. This whole process flickers by in an instant and a new user would miss my welcome page entirely.It appears as though that
false null
print happens exactly when#access_token=...
is removed from the URL (I screen recorded so I could move frame-by-frame through the redirects).Returning to
/welcome
and refreshing prints the following to the console:With no redirect to /signin, so it's definitely just when arriving fresh from the email link. However, it's probably notable that the
user
object hasnull
forconfirmed_at
andcreated_at
or any other date values, anduserDetails
remainsundefined
the whole time in both page load scenarios.As a temporary fix, I've started storing the
session
fromonAuthStateChange()
withuseState()
, watching that from theuseEffect()
and including it in the list of "and not"s before pushing the user to /signin but that feels like it should be unnecessary!