Blank Page on throw notFound() in beforeLoad #7470
|
I have an issue where if I try this exact // serverFn
export const getCalcById = createServerFn({
method: 'GET',
})
....
const someData = someAction({
...
})
if (!someData) {
throw new Error('someMessage')
}
return someData
})
// query options
export const someQueryOptions= (someId: string) =>
queryOptions({
queryKey: ['some', someId],
queryFn: () =>
getSomeDataById({
data: {
id: someId,
},
}),
})
// this works fine but if I swap for a beforeLoad I get a blank screen if the above serverFn throws an error
loader: async ({ context: { queryClient }, params: { someId } }) => {
try {
// This throws an error if it can't return the data
const someData = await queryClient.ensureQueryData(someQueryOptions(someId))
return { someData }
} catch (e) {
throw notFound()
}
},
// this wont work
beforeLoad: async ({ context: { queryClient }, params: { someId } }) => {
try {
// This throws an error if it can't return the data
const someData = await queryClient.ensureQueryData(someQueryOptions(someId))
return { someData }
} catch (e) {
// blank screen
throw notFound()
}
},
// this is in the exact same route definition as the `beforeLoad` that I'm trying to get to work
notFoundComponent: () => {
const { someId } = Route.useParams()
return (
<EntityNotFound
linkOptions={{ to: '/' }}
/>
)
},
|
Replies: 2 comments
|
I changed to errorComponent and that fixed the issue, as the api call throws an error, it's not a case of using the not found, rather the error component |
|
This is a quirk of where Thrown from a Fix is to give the root a not-found component: export const Route = createRootRoute({
notFoundComponent: () => <div>Not found</div>,
component: RootComponent,
})or set it once on the router: const router = createRouter({
routeTree,
defaultNotFoundComponent: () => <div>Not found</div>,
})Switching to |
This is a quirk of where
notFound()gets caught depending on which hook throws it.Thrown from a
loader, it renders the nearest route's ownnotFoundComponent. But thrown frombeforeLoad, it always bubbles up to the root route'snotFoundComponent, becausebeforeLoadruns before the route's data is guaranteed to be there, so the router can't safely render that route's own boundary. If your__rootroute (or the router'sdefaultNotFoundComponent) doesn't define one, there's nothing to render and you get the blank page. That's why the loader version worked and thebeforeLoadversion didn't.Fix is to give the root a not-found component: