Unexpected SolidStart Behavior On Vercel. Can You Help?

I have an AuthContextProvider that works on npm run dev but doesn't work on Vercel. I'm lost. Any help would be appreciated. Here's the flow: 1. I'm using a Solid store (createStore) to store auth state. 2. When the auth state changes, I update the Solid store. 3. If a user is authenticated AND they are on a page that has /auth in the pathname, I redirect the user to the app dashboard. This prevents authenticated users from accessing sign-in or sign-up pages. Everything works as expected when running npm run dev. When a user signs in on the /auth/sign-in page: 1. An auth state change occurs. 2. I set isAuthenticated to true 3. Then, I redirect the user to the app dashboard. After deploying to Vercel, the redirect stopped working. After signing in, the app stays on the /auth/sign-in page. I added a console.log to check both conditions, and both are true, but the redirect doesn't work. If I refresh my browser, the redirect occurs. Why is this happening? Does it have something to do with caching at Vercel? I'm using the latest version of SolidStart in SSR mode. Here's the code.
// Set up a store to track auth state
const defaultAuthState: SupabaseAuthData = {
isAuthenticated: false,
isLoading: true,
supabaseSession: null,
isAdmin: false,
};

const [authStore, setAuthStore] = createStore(defaultAuthState);

const { data: { subscription }, } = supabase.auth.onAuthStateChange(async (_event, session) => {
// Check to see if there is a session.
if (!!session) {
// A session exists. Update the auth store
setAuthStore({ isAuthenticated: true, supabaseSession: session, isAdmin: adminUser });

console.log(authStore.isAuthenticated); // result true
console.log(location.pathname.includes("/auth"); // result true

// NOT WORKING
if (location.pathname.includes("/auth") && authStore.isAuthenticated) {
navigate(`/${appRoute}`, { replace: true });
}
}
});
// Set up a store to track auth state
const defaultAuthState: SupabaseAuthData = {
isAuthenticated: false,
isLoading: true,
supabaseSession: null,
isAdmin: false,
};

const [authStore, setAuthStore] = createStore(defaultAuthState);

const { data: { subscription }, } = supabase.auth.onAuthStateChange(async (_event, session) => {
// Check to see if there is a session.
if (!!session) {
// A session exists. Update the auth store
setAuthStore({ isAuthenticated: true, supabaseSession: session, isAdmin: adminUser });

console.log(authStore.isAuthenticated); // result true
console.log(location.pathname.includes("/auth"); // result true

// NOT WORKING
if (location.pathname.includes("/auth") && authStore.isAuthenticated) {
navigate(`/${appRoute}`, { replace: true });
}
}
});
3 Replies
ChrisThornham
ChrisThornhamOP4mo ago
Here's an update. I can correct the behavior if I add a 1 second delay between setAuthStore and the if check for navigation. So, it appears that setAuthStore hasn't finished setting the auth state before the if statement runs. Is it possible to await setAuthState? Or correct this some other way? Adding a delay feels a bit hacky. Also, why would this happen on Vercel but not in my local environment? Is there a network lag that occurs when calling setAuthState on Vercel that doesn't occur locally? For anyone who might stumble upon this in the future, I solved the problem by moving the navigation logic outside of onAuthStateChange and into it's own createEffect(). This way, the if check only runs when authStore has updated.
Madaxen86
Madaxen864mo ago
As an alternative instead of using a store you can use cached server function. If you call this in a layout, the cached functioned will persist (not revalidate) on route changes within the layout. And then you can use actions to invalidate the function, use a setInterval in the layout’s onMount to refresh the session etc. And it will automatically revalidate when user navigate to un-authed routes and come back to the auth-ed routes. I am afk in vacation so I can’t share code. But I really like this pattern.
ChrisThornham
ChrisThornhamOP4mo ago
Interesting! Thanks for mentioning this.
Want results from more Discord servers?
Add your server