DEV Community

Md. Khalid Hossen
Md. Khalid Hossen

Posted on

Configure tanstack router into vite project with authenticate routes, active routes.

Tanstack router is a file based routing systems like next js. routing is pretty easy to configure but you need to do it carefully. Otherwise, it will kill your energy. Enough talk lets start:
you need to install: yarn add @tanstack/react-router
and you need to add dev dependency: yarn add -D @tanstack/router-devtools @tanstack/router-plugin

At 1st you need to configure vite and make it confortable with the projects. please make perfectly otherwise layout systems may not work as it should. Navigate vite.config.ts file and flow my code below:

import {TanStackRouterVite} from '@tanstack/router-plugin/vite'

import this into vite.config.ts file then add plugin after react():
TanStackRouterVite({
routeToken: 'layout',
}),

Now, you need change your main.tsx file:
here i have create with context and pass my authentications where for authenticated routes and i aslo create hooks with zustand for my authentications.

import {StrictMode} from 'react'
import ReactDOM from 'react-dom/client'
import {createRouter, RouterProvider} from '@tanstack/react-router'


import './index.css'
import {routeTree} from './routeTree.gen'
import useAuthToken from './hooks/useAuthToken'


const rootElement = document.getElementById('root')!

const router = createRouter({
  routeTree,
  context: {authentication: undefined!},
})

declare module '@tanstack/react-router' {
  interface Register {
    router: typeof router
  }
}


function App() {
  const authentication = useAuthToken()
  return (
        <RouterProvider router={router} context={{authentication, canAccessPage}} />
  )
}

if (!rootElement.innerHTML) {
  const root = ReactDOM.createRoot(rootElement)
  root.render(
    <StrictMode>
      <App />
    </StrictMode>,
  )
}

Enter fullscreen mode Exit fullscreen mode

useAuthtoke hooks::

import {create} from 'zustand'
import {persist} from 'zustand/middleware'

type State = {
  authToken?: string
}

type Action = {
  setAuthToken: (token: string) => void
  removeAuthToken: () => void
}

export type AuthTokenProps = State & Action


const initialState: State = {
  authToken: undefined,
}

const useAuthToken = create<AuthTokenProps>()(
  persist(
    set => ({
      ...initialState,
      setAuthToken: token => {
        set({authToken: token})
      },
      removeAuthToken: () => {
        set(initialState)
      },
    }),
    {
      name: 'auth',
    },
  ),
)

export default useAuthToken

Enter fullscreen mode Exit fullscreen mode

Now, you need to configure your __root.tsx file you need to link context form here using createRootRouteWithContext becuase you need your context for authenticate routes :

import * as React from 'react'
import {Outlet, createRootRouteWithContext} from '@tanstack/react-router'

import {AuthTokenProps} from '@/hooks/useAuthToken'

type RouterContext = {
  authentication: AuthTokenProps
}

export const Route = createRootRouteWithContext<RouterContext>()({
  component: () => (
    <React.Fragment>
      <Outlet />
    </React.Fragment>
  ),
})

Enter fullscreen mode Exit fullscreen mode

Since we already know tanstack router is allow file based routing we need to create One file and One folder under routes folder. Folder and file structer will be like this:

*routes
| __root.tsx
| _authenticated.tsx
| _authenticated
| dashboard.tsx
| login.tsx
*

Note: here _authenticated folder hold your authenticated routes and others routes will be your unauthenticated routes. here login is unauthenticate route and dashboard will be your authenticate route.

Now you need to configure your layout file which is _authenticated.tsx

import React from 'react'
import {createFileRoute, Outlet, redirect} from '@tanstack/react-router'

export const Route = createFileRoute('/_authenticated')({
  beforeLoad: async ({context}) => {
    const {authToken} = context.authentication
    if (!authToken) {
      throw redirect({to: '/login'})
    }
  },
  component: () => (
      <React.Fragment>
          <div className='flex flex-1 h-[90vh] flex-col gap-4 p-4 pt-0 top-14 absolute w-full'>
            <Outlet />
          </div>
      </React.Fragment>
  ),
})

Enter fullscreen mode Exit fullscreen mode

Note: on beforeLoad is callback functions where you can get context which you have set early if authtoken is available during that time you can accesss dashboard otherwise it will redirect to login page.

Oh one things don't forget to add authtoken after login.

export const Route = createFileRoute('/login/')({
  beforeLoad: async ({context}) => {
    const {authToken} = context.authentication
    if (authToken) throw redirect({to: '/dashboard'})
  },
  component: LoginForm,
})
--------------------- after login in successfully you need to setAuthtoken and router invalidate ---------------------
    {
      setAuthToken(access) // here you will get 
      router.invalidate()
    }
Enter fullscreen mode Exit fullscreen mode

Now actives routes link for active link:

 <Link 
 className='py-3 [&.active]:font-bold [&.active]:text-sky-500'
 to={subItem.url}
 activeOptions={{exact: true, includeSearch: false}}>
  Dashbaord
</Link>
Enter fullscreen mode Exit fullscreen mode

here you need to pass exact: true for exact path match if you have search query of that routes during that time you need to pass includeSearch: false . Otherwise when you have added query in your path during that time active link will be deactiv because you have pass exact true.

Top comments (0)