T
TanStack2y ago
stormy-gold

beforeLoad with file based routing?

Hi, I need a beforeLoad and i'm using file based routing but the docs only mention how to do this when you're defining the rotes through code as far as I can see. Can someone point to me on how to add a beforeLoad? My use case is that I want a beforeLoad in my root index.component.tsx to check if i'm authenticated and redirect to /login if not. I'm checking the docs here: https://tanstack.com/router/latest/docs/framework/react/guide/authenticated-routes
Authenticated Routes | TanStack Router Docs
Authentication is an extremely common requirement for web applications. In this guide, we'll walk through how to use TanStack Router to build protected routes, and how to redirect users to login if they try to access them. The route.beforeLoad Option
3 Replies
stormy-gold
stormy-gold2y ago
If you need to use the beforeLoad callback, it need to be added to the route definition. BTW the .component syntax has been depcrecated in favor of.lazy instead. So the route set up would be like this.
src/routes
my-route.lazy.tsx <- your component would go here
my-route.tsx <- your route configuration would go here
index.tsx
src/routes
my-route.lazy.tsx <- your component would go here
my-route.tsx <- your route configuration would go here
index.tsx
If you just create the my-route.tsx file and hit save, the vite-plugin should scaffold the base configuration. Then it can be changed to suit your needs.
// src/routes/my-route.tsx
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute("/my-route")({
beforeLoad: () => {
/* Add your logic here */
},
})
// src/routes/my-route.tsx
import { createFileRoute } from '@tanstack/react-router'

export const Route = createFileRoute("/my-route")({
beforeLoad: () => {
/* Add your logic here */
},
})
other-emerald
other-emerald2y ago
I use beforeLoad for the exact same reason, here is my code, in case it helps:
beforeLoad: async () => {
if (!localStore.authToken.get())
throw redirect({ to: '/login' })

// Make a call to the api to make sure,
// the user is authenticated.
const user = await apiUtils.auth.getUser.fetch()
return { user, organisation }
},
beforeLoad: async () => {
if (!localStore.authToken.get())
throw redirect({ to: '/login' })

// Make a call to the api to make sure,
// the user is authenticated.
const user = await apiUtils.auth.getUser.fetch()
return { user, organisation }
},
Then I use a custom fetch to catch 401 'UNAUTHORIZED', in case the token is invalid:
async fetch(...params: Parameters<typeof fetch>) {
const response = await fetch(...params)

// If token is invalid, remove it from localStore + reload
if (response.status === 401) {
localStore.token.delete()
router.invalidate()
}

return response
}
async fetch(...params: Parameters<typeof fetch>) {
const response = await fetch(...params)

// If token is invalid, remove it from localStore + reload
if (response.status === 401) {
localStore.token.delete()
router.invalidate()
}

return response
}
stormy-gold
stormy-gold2y ago
Yup! that looks good. But to answer your OP, you'll need to define the route definition to be able to use the beforeLoad and loader callbacks.

Did you find this page helpful?