oedotme / generouted

Generated file-based routes for Vite
https://stackblitz.com/github.com/oedotme/generouted/tree/main/explorer
MIT License
1.02k stars 48 forks source link

How can I achieve protected routes based on any value? #111

Closed candogusyilmaz closed 1 year ago

candogusyilmaz commented 1 year ago

Hi, I'm trying to achieve something like this:

When user changes to a page if that page has the below value:

export const GUARD = "any_value";

I want to search in user's permissions. Is it possible to create something like this?

oedotme commented 1 year ago

Hey @candogusyilmaz, I usually define protected routes in one place inside of a wrapper component to handle the redirections based on auth state.

Here's an example from Render template:

// src/config/redirects.tsx

import { Navigate, useLocation } from 'react-router-dom'

import { useAuth } from '@/context'
import { Path } from '@/router'

const PRIVATE: Path[] = ['/logout']
const PUBLIC: Path[] = ['/login']

export const Redirects = ({ children }: { children: JSX.Element }) => {
  const auth = useAuth()
  const location = useLocation()

  const authedOnPublicPath = auth.token && PUBLIC.includes(location.pathname as Path)
  const unAuthedOnPrivatePath = !auth.token && PRIVATE.includes(location.pathname as Path)

  if (authedOnPublicPath) return <Navigate to="/" replace />
  if (unAuthedOnPrivatePath) return <Navigate to="/login" replace />

  return children
}

The <Redirects> component can be used at src/pages/_app.tsx to wrap the <Outlet> component:

// src/pages/_app.tsx

import { Outlet } from 'react-router-dom'

import { Redirects } from '@/config'

export default function App() {
  return (
    <section>
      <header>
        <nav>...</nav>
      </header>

      <main>
        <Redirects>
          <Outlet />
        </Redirects>
      </main>
    </section>
  )
}


If you want to move the definition of the protected routes to each file, I'm thinking it can be as following:

Here are some related issue #28, #103

Hope that helps!

candogusyilmaz commented 1 year ago

Thank you for taking the time to answer.