T
TanStack2y ago
extended-salmon

Context and router

hey everyone, someone know how can I access to context from a component ? (without calling it a second time, because i call it in the route for check the auth)
21 Replies
xenial-black
xenial-black2y ago
you could try useRouter().options.context or even useRouteContext() e.g
const context = useRouteContext({from: "/YourRoute"})
const context = useRouteContext({from: "/YourRoute"})
eastern-cyan
eastern-cyan2y ago
How do I access the router context from the Wrap component ? Hooks are not available
xenial-black
xenial-black2y ago
the wrap component?
eastern-cyan
eastern-cyan2y ago
RouterOptions | TanStack Router Docs
RouterOptions type The RouterOptions type contains all of the options that can be used to configure a router instance.
eastern-cyan
eastern-cyan2y ago
I'm using SSR, and I try to set dynamically imported messages for i18n to the context, and then initialize my IntlProvider with it
genetic-orange
genetic-orange2y ago
The Wrap component doesn't have access to the router yet. It's an outer wrap InnerWrap does have access to the router though Try useRouter.options.context like @apple mentioned
eastern-cyan
eastern-cyan2y ago
It works on the server, but not on the client https://codesandbox.io/p/devbox/vigilant-alex-fvctcj?file=%2Fsrc%2Frouter.tsx Maybe I'm missing something
genetic-orange
genetic-orange2y ago
Hmmm Does it show up later? Or is it always undefined on the client e.g. after navigating somewhere Oh I see the issue You are injecting the messages in your server entry, but not your client entry And you might have incorrectly assumed that context is serialized, transferred and hydrated to the client It's not Context should be fulfilled consistently for both server and client If you need something to be serialized and sent with to the client from the server, you'll have to put it in the root loader I will admit, router context has been confusing for both consumers and us maintainers We're taking experiences like this as feedback for how to do it better. Most of it revolves around the expectations of serialization from the server to the client A good example of why that's problematic... if you put a non-primitive in context, like a client or instance, it wouldn't get serialized properly. So we can guaranty serialization just yet.
eastern-cyan
eastern-cyan2y ago
Alright! Thank you for your help! Maybe adding an example for i18n and SSR would help, I'll have the same issue with authentication
genetic-orange
genetic-orange2y ago
I agree We really need that
eastern-cyan
eastern-cyan2y ago
I guess I'll need to serialize the session and pass it to the client
genetic-orange
genetic-orange2y ago
Would you be up for the challenge? I honestly dont' know much about it Just so you know, there is a way to hook into the router to do serialization
genetic-orange
genetic-orange2y ago
External Data Loading | TanStack Router Docs
⚠️ This guide is geared towards external state management libraries and their integration with TanStack Router for data fetching, ssr, hydration/dehydration and streaming. If you haven't read the standard Data Loading guide To Store or to Coordinate?
genetic-orange
genetic-orange2y ago
But it happens outside of the router, which may not fit your use case
eastern-cyan
eastern-cyan2y ago
I don't know if I'm the most qualified for that 😅 I'm just getting started with SSR and I didn't need to care about all that with Next.js because it was straighforward with Next-Auth
genetic-orange
genetic-orange2y ago
yep We're fresh on the scene 😉 It's getting worked out slowly though Ideally we'll have a first-class TanStack Router Auth solution someday, but we're out a ways from that
eastern-cyan
eastern-cyan2y ago
Next-Auth has been renamed to Auth.js and it's agnostic now, we should be able to plug in
genetic-orange
genetic-orange2y ago
That would be cool We'll likely need to think about it from both the SPA and the Full Stack approach I've been really busy working on the full-stack story for TSR, so we can figure out our constraints before movign forward But the SPA side is easier to figure out in that regard
eastern-cyan
eastern-cyan2y ago
Yeah sure! React becomes complicated with SSR, RSC and all that stuff I'll try to setup SSR with i18n tomorrow, it will be a first step Thank you for your help!
genetic-orange
genetic-orange2y ago
I hope it was actually helpful 🙂
extended-salmon
extended-salmonOP2y ago
sorry, I havent saw your response but this is my code:
import { Container } from "@/components/container";
import {createFileRoute, redirect} from "@tanstack/react-router";
import {Accordion, AccordionContent, AccordionItem, AccordionTrigger} from "@/components/ui/accordion.tsx";
import {useContext} from "react";



export const Route = createFileRoute('/account')({
beforeLoad: ({ context, location }) => {
if (!context.auth.isAuthenticated) {
throw redirect({
to: '/',
search: {
redirect: location.href,
},
})
}
},
component: () => AccountComponent(),
});

function AccountComponent() {

const context = useContext({}).router.context

return (
<Container>
<Accordion type="single" collapsible className="w-10/12 text-duckyblue font-londrina text-xl">
<AccordionItem value="item-1">
<AccordionTrigger>Informations personnelles</AccordionTrigger>
<AccordionContent>
<PersonalInformationForm user={context}/>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2" disabled={user.type == "oauth"} >
<AccordionTrigger disabled={user.type == "oauth"} className={user.type == "oauth" ? "text-gray-500": ""}>Compte</AccordionTrigger>
<AccordionContent>
todo:
</AccordionContent>
</AccordionItem>
</Accordion>
</Container>
)
}
import { Container } from "@/components/container";
import {createFileRoute, redirect} from "@tanstack/react-router";
import {Accordion, AccordionContent, AccordionItem, AccordionTrigger} from "@/components/ui/accordion.tsx";
import {useContext} from "react";



export const Route = createFileRoute('/account')({
beforeLoad: ({ context, location }) => {
if (!context.auth.isAuthenticated) {
throw redirect({
to: '/',
search: {
redirect: location.href,
},
})
}
},
component: () => AccountComponent(),
});

function AccountComponent() {

const context = useContext({}).router.context

return (
<Container>
<Accordion type="single" collapsible className="w-10/12 text-duckyblue font-londrina text-xl">
<AccordionItem value="item-1">
<AccordionTrigger>Informations personnelles</AccordionTrigger>
<AccordionContent>
<PersonalInformationForm user={context}/>
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2" disabled={user.type == "oauth"} >
<AccordionTrigger disabled={user.type == "oauth"} className={user.type == "oauth" ? "text-gray-500": ""}>Compte</AccordionTrigger>
<AccordionContent>
todo:
</AccordionContent>
</AccordionItem>
</Accordion>
</Container>
)
}
this const context = useContext().router.context is not right but const context = useRouteContext({from: "/account"}); looks great btw

Did you find this page helpful?