T
TanStack4w ago
adverse-sapphire

Context not typed

Hi everyone. My context appear as not typed. This is my code:
router.tsx
import type { AppAbility } from '@code-shifters/jps-auth';
import type { QueryClient } from '@tanstack/react-query';
import { queryClient } from '~/lib/query-client';
import { routeTree } from '~/routeTree.gen';
import type { SignInResponseSchema } from '~/shared/schemas/sign-in.schema';
import { loggedUserStoreState } from '~/store/user.store';

/**
* Router context type.
*/
type RouterContext = {
queryClient: QueryClient;
user: SignInResponseSchema | null;
permissions?: AppAbility | null;
};

/**
* Router instance with context data.
*/
const router = createRouter({
routeTree,
defaultPreload: 'intent',
context: {
queryClient,
// TODO: not working!
user: loggedUserStoreState.get() ?? null,
permissions: loggedUserStoreState.getPermissions(),
},
});

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

export { router, type RouterContext };
import type { AppAbility } from '@code-shifters/jps-auth';
import type { QueryClient } from '@tanstack/react-query';
import { queryClient } from '~/lib/query-client';
import { routeTree } from '~/routeTree.gen';
import type { SignInResponseSchema } from '~/shared/schemas/sign-in.schema';
import { loggedUserStoreState } from '~/store/user.store';

/**
* Router context type.
*/
type RouterContext = {
queryClient: QueryClient;
user: SignInResponseSchema | null;
permissions?: AppAbility | null;
};

/**
* Router instance with context data.
*/
const router = createRouter({
routeTree,
defaultPreload: 'intent',
context: {
queryClient,
// TODO: not working!
user: loggedUserStoreState.get() ?? null,
permissions: loggedUserStoreState.getPermissions(),
},
});

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

export { router, type RouterContext };
__root.tsx
const Route = createRootRouteWithContext<RouterContext>()({
component: () => (
<QueryClientProvider client={queryClient}>
<Toaster
position="bottom-left"
closeButton
duration={10000}
icons={{
error: <CircleX />,
info: <Info />,
success: <CircleCheck />,
warning: <AlertTriangle />,
}}
/>

<Outlet />

{/* Dev Tools from TanStack */}
<ReactQueryDevtools buttonPosition="bottom-right" client={queryClient} />
<TanStackRouterDevtools
position="bottom-right"
toggleButtonProps={{
style: {
zIndex: 10,
right: 66,
},
}}
/>
</QueryClientProvider>
),
});

export { Route };
const Route = createRootRouteWithContext<RouterContext>()({
component: () => (
<QueryClientProvider client={queryClient}>
<Toaster
position="bottom-left"
closeButton
duration={10000}
icons={{
error: <CircleX />,
info: <Info />,
success: <CircleCheck />,
warning: <AlertTriangle />,
}}
/>

<Outlet />

{/* Dev Tools from TanStack */}
<ReactQueryDevtools buttonPosition="bottom-right" client={queryClient} />
<TanStackRouterDevtools
position="bottom-right"
toggleButtonProps={{
style: {
zIndex: 10,
right: 66,
},
}}
/>
</QueryClientProvider>
),
});

export { Route };
Any idea what I'm doing wrong?
No description
25 Replies
exotic-emerald
exotic-emerald4w ago
can you please provide a full example by forking one of the stackblitz router examples?
adverse-sapphire
adverse-sapphireOP4w ago
app.tsx
/**
* Component with Router Provider and context data.
*/
const RouterProviderWithContext = () => {
const user = loggedUserStoreState.get();
const permissions = loggedUserStoreState.getPermissions();

return (
<RouterProvider
router={router}
context={{
queryClient,
user,
permissions,
}}
/>
);
};

function App() {
return (
<QueryClientProvider client={queryClient}>
<link rel="shortcut icon" href="/icon.svg" type="image/svg+xml" />

<RouterProviderWithContext />
</QueryClientProvider>
);
}

export { App };
/**
* Component with Router Provider and context data.
*/
const RouterProviderWithContext = () => {
const user = loggedUserStoreState.get();
const permissions = loggedUserStoreState.getPermissions();

return (
<RouterProvider
router={router}
context={{
queryClient,
user,
permissions,
}}
/>
);
};

function App() {
return (
<QueryClientProvider client={queryClient}>
<link rel="shortcut icon" href="/icon.svg" type="image/svg+xml" />

<RouterProviderWithContext />
</QueryClientProvider>
);
}

export { App };
Version: "@tanstack/react-router": "^1.131.36",
exotic-emerald
exotic-emerald4w ago
please fork that example and modify so it matches your issue: https://tanstack.com/router/latest/docs/framework/react/examples/quickstart-file-based
React TanStack Router Quickstart File Based Example | TanStack Rout...
An example showing how to implement Quickstart File Based in React using TanStack Router.
adverse-sapphire
adverse-sapphireOP4w ago
For that I need to add almost everything, tanstack query, legend state, etc...
adverse-sapphire
adverse-sapphireOP4w ago
I think this could be the problem, but no idea how to solve it
No description
adverse-sapphire
adverse-sapphireOP4w ago
Already update my tsconfig but nothing happens Didn't solve the issue of the context
exotic-emerald
exotic-emerald4w ago
rspack bundler has no influence on router types well without a reproducer we won't be able to find out the issue. try adding one thing at time to find out which one causes it
adverse-sapphire
adverse-sapphireOP4w ago
const router = createRouter({
routeTree,
context: {
queryClient,
// user: loggedUserStoreState.get() ?? null,
// permissions: loggedUserStoreState.getPermissions(),
},
defaultPreload: 'intent',
// Since we're using React Query, we don't want loader calls to ever be stale
// This will ensure that the loader is always called when the route is preloaded or visited
defaultPreloadStaleTime: 0,
scrollRestoration: true,
});
const router = createRouter({
routeTree,
context: {
queryClient,
// user: loggedUserStoreState.get() ?? null,
// permissions: loggedUserStoreState.getPermissions(),
},
defaultPreload: 'intent',
// Since we're using React Query, we don't want loader calls to ever be stale
// This will ensure that the loader is always called when the route is preloaded or visited
defaultPreloadStaleTime: 0,
scrollRestoration: true,
});
Leve it only with queryClient but same result, when try to access context is typed as {} The problem is that works, but isn't typed
adverse-sapphire
adverse-sapphireOP4w ago
console.log(context) - loader function
No description
adverse-sapphire
adverse-sapphireOP4w ago
No description
exotic-emerald
exotic-emerald4w ago
make this a complete example please
adverse-sapphire
adverse-sapphireOP4w ago
Sorry didn't understand?
adverse-sapphire
adverse-sapphireOP4w ago
The last print is from my _auth.tsx
No description
adverse-sapphire
adverse-sapphireOP4w ago
My index.tsx
No description
adverse-sapphire
adverse-sapphireOP4w ago
My root is very simple
const Route = createRootRouteWithContext<RouterContext>()({
component: App,
});
const Route = createRootRouteWithContext<RouterContext>()({
component: App,
});
The app is very simple is only a outlet The _auth is where I defined my authentication layout
const Route = createFileRoute('/_auth')({
component: AuthLayout,
loader: ({ context }) => {
// If user is not null, redirect to admin page
if (context.user !== null) {
throw redirect({
to: '/admin',
});
}
},
});
const Route = createFileRoute('/_auth')({
component: AuthLayout,
loader: ({ context }) => {
// If user is not null, redirect to admin page
if (context.user !== null) {
throw redirect({
to: '/admin',
});
}
},
});
and then my typescript give me error on the context.user saying that user doesn't exist on {}
exotic-emerald
exotic-emerald4w ago
this
adverse-sapphire
adverse-sapphireOP4w ago
ON root route is correctly typed
No description
adverse-sapphire
adverse-sapphireOP4w ago
No description
adverse-sapphire
adverse-sapphireOP4w ago
And if I do this:
createFileRoute<'/_auth', typeof RootRoute>('/_auth')(....)
createFileRoute<'/_auth', typeof RootRoute>('/_auth')(....)
Works too...
exotic-emerald
exotic-emerald4w ago
still waiting for a complete example that reproduces the issue
secure-lavender
secure-lavender3w ago
@TutoDS Try :
export const Route = createRootRouteWithContext<RouterContext>()({
component: App,
});
export const Route = createRootRouteWithContext<RouterContext>()({
component: App,
});
instead of
const Route = createRootRouteWithContext<RouterContext>()({
component: App,
});`
const Route = createRootRouteWithContext<RouterContext>()({
component: App,
});`
I think tanstack router is looking specifically for export const Route and doesn't use the module system so export { Router } wouldn't work. Similarly using a variable name other than Route doesn't work either. This caught me out.
adverse-sapphire
adverse-sapphireOP2w ago
Thanks 🙏
adverse-sapphire
adverse-sapphireOP2w ago
Now facing the issue with search params too
No description
adverse-sapphire
adverse-sapphireOP2w ago
Property redirect-to does not exist on type {}. Already try to use zod adapter on validate search but didn't work
secure-lavender
secure-lavender2w ago
Keep debugging, you'll find a solution I'm sure.

Did you find this page helpful?