Closed hugo-instasense closed 1 year ago
Hey @hugo-instasense, I usually do something similar, here's a snippet using the matchPath
util from react-router-dom
:
import { matchPath, Navigate, useLocation } from 'react-router-dom'
import { useAuth } from '@/context'
const PRIVATE = ['/logout', '/dynamic/:timestamp']
const PUBLIC = ['/login']
const hasMatch = (paths: string[], path: string) => paths.some((x) => matchPath(x, path))
export const Guard = ({ children }: { children: JSX.Element }) => {
const auth = useAuth()
const { pathname } = useLocation()
const authedOnPublicPath = auth.token && PUBLIC.includes(pathname)
const unAuthedOnPrivatePath = !auth.token && (PRIVATE.includes(pathname) || hasMatch(PRIVATE, pathname))
if (authedOnPublicPath) return <Navigate to="/" replace />
if (unAuthedOnPrivatePath) return <Navigate to="/login" replace />
return <>{children}</>
}
I'm thinking to include the original full path at each route object to directly compare the two paths without using the matchPath
utility, will probably update it once that's supported by generouted
.
Love this library, great work! One thing though that I am not sure how to do is add a slug path to the PRIVATE paths array.
Example say location.pathName = '/order/1043', currently the PRIVATE paths matches on exact ones. Would be cool to specify:
Here is the modified
guard.tsx
, this might be a great example to add the the project?