S
SolidJS16mo ago
Nin

Navigate user in login/logout functions

I'm trying to make it generic to send my users either to the main page or to the login page when they either login or logout but I'm having trouble doing this in a generic way.
import { createContext, createSignal, useContext } from "solid-js"
import type { Session } from "@supabase/supabase-js"

import supabase from "../supabase"

export const AuthContext = createContext<{
session: () => Session | null
login: (session: Session | null) => void
logout: () => void
}>()

const [session, setSession] = createSignal<Session | null>(null)

export const authContext = {
session: () => session(),
login: (supabaseSession: Session | null) => {
setSession(supabaseSession)
},
logout: () => {
setSession(null)
supabase.auth.signOut()
}
}
export const useAuth = () => useContext(AuthContext)!
import { createContext, createSignal, useContext } from "solid-js"
import type { Session } from "@supabase/supabase-js"

import supabase from "../supabase"

export const AuthContext = createContext<{
session: () => Session | null
login: (session: Session | null) => void
logout: () => void
}>()

const [session, setSession] = createSignal<Session | null>(null)

export const authContext = {
session: () => session(),
login: (supabaseSession: Session | null) => {
setSession(supabaseSession)
},
logout: () => {
setSession(null)
supabase.auth.signOut()
}
}
export const useAuth = () => useContext(AuthContext)!
This is my Auth Provider for example, I would like to add to the login/logout sessions a redirect. I've tried to use useNavigate but get the error it should be wrapped in a <Router />, I've tried using return <Navigate href="/" /> but this doesn't work either. Anyone able to help me out here?
3 Replies
Martnart
Martnart16mo ago
Usually Contexts are part of a Provider component. If you did that, I think it would have the behavior that you want. Also a bit suspect that you have a session signal at the root level of the page. If you'd have it inside a Provider it'd be scoped as would be expected.
<AuthProvider>
...
<Routes />
...
</AuthProvider>
<AuthProvider>
...
<Routes />
...
</AuthProvider>
Nin
NinOP16mo ago
@martnart Maybe I should make my Auth Guard and Auth Provider just a single component? This is currently my Auth Guard component which I have in the root.tsx file.
import type { ComponentProps } from "solid-js"

import { useNavigate } from "@solidjs/router"

import { AuthContext, authContext } from "~/lib/providers/auth-provider"
import supabase from "~/lib/supabase"

export default function AuthGuard(props: ComponentProps<"div">) {
const navigate = useNavigate()


supabase.auth.getSession().then(({ data, error }) => {
const { session } = data

if (session === null || error) {
navigate("/auth/signin")
} else {
authContext.login(session)
}
})

return <AuthContext.Provider value={authContext}>{props.children}</AuthContext.Provider>
}
import type { ComponentProps } from "solid-js"

import { useNavigate } from "@solidjs/router"

import { AuthContext, authContext } from "~/lib/providers/auth-provider"
import supabase from "~/lib/supabase"

export default function AuthGuard(props: ComponentProps<"div">) {
const navigate = useNavigate()


supabase.auth.getSession().then(({ data, error }) => {
const { session } = data

if (session === null || error) {
navigate("/auth/signin")
} else {
authContext.login(session)
}
})

return <AuthContext.Provider value={authContext}>{props.children}</AuthContext.Provider>
}
Root.tsx
<AuthGuard>
<Navbar />
<Routes>
<Route path="/auth">
<Route path={["/signin", "/signup"]} component={Authentication} data={determineAuthMode} />
</Route>
<FileRoutes />
</Routes>
</AuthGuard>
<AuthGuard>
<Navbar />
<Routes>
<Route path="/auth">
<Route path={["/signin", "/signup"]} component={Authentication} data={determineAuthMode} />
</Route>
<FileRoutes />
</Routes>
</AuthGuard>
I think I'm mixing two things up together. Will look into this by making my AuthGuard a simple function that just guards, and make the provider the one that actually retrieves the session
Martnart
Martnart16mo ago
This is the way

Did you find this page helpful?