T
TanStack12mo ago
stormy-gold

Can I have server only context that i can access in my router ?

I'm experimenting with Tanstack start and tRPC. I want to be able to prefetch some queries in my loader and by dehadryte and hydrate the queryClient get the data on the client. I'm using createServerSideHelpers to create the context I want to use in the router but it can't be packed in the client bundle. I've try to create separate routers one for the client and one for the server but it doesn't seems to work like I expect: type are not ok and the code is packed in the server bundle. Do you have any exemple of having server only context ? do you have any input about how I can achieve prefetch with tanstack start ? is there any trick with vite to have on router definition but different code depending on if we are on the server or the client ?
Server-Side Helpers | tRPC
The server-side helpers provides you with a set of helper functions that you can use to prefetch queries on the server. This is useful for SSG, but also for SSR if you opt not to use ssr: true.
5 Replies
sensitive-blue
sensitive-blue12mo ago
can you please explain in more detail what you want to do? what does "server only" mean for you? but you still want to access it on client?
stormy-gold
stormy-goldOP12mo ago
I want to achieve something like that:
export const Route = createFileRoute("/post")({
// this trpc instance is generated by createServerSideHelpers and will execurte code on the server without going through an API
loader: async ({ context: { trpc } }) => {
await trpc.post.all.prefetch();
},
component: PostComponent,
});

function PostComponent() {
// this trpc instance is the client side trpc instance that will call the API
// after hydration you won't have any calls to the API,
// because the data is already fetched on the server and loaded in the cache with hydration.
// if you add a posts you can invalidate the cache and refetch the data through the API thanks to RQ
const posts = trpc.post.all.useQuery();
return (
<div className="flex h-screen w-screen items-center justify-center">
{posts.data?.map((post) => <div key={post.id}>{post.title}</div>)}
</div>
);
}
export const Route = createFileRoute("/post")({
// this trpc instance is generated by createServerSideHelpers and will execurte code on the server without going through an API
loader: async ({ context: { trpc } }) => {
await trpc.post.all.prefetch();
},
component: PostComponent,
});

function PostComponent() {
// this trpc instance is the client side trpc instance that will call the API
// after hydration you won't have any calls to the API,
// because the data is already fetched on the server and loaded in the cache with hydration.
// if you add a posts you can invalidate the cache and refetch the data through the API thanks to RQ
const posts = trpc.post.all.useQuery();
return (
<div className="flex h-screen w-screen items-center justify-center">
{posts.data?.map((post) => <div key={post.id}>{post.title}</div>)}
</div>
);
}
The main idea is to have the full page render on the server and have minimum loader. I don't want to use serverFunction because you don't have the validation layer and you can't use them outside tanstack start start I believe ( or can you ? ) and I want to share muse my tRPC router in a mobile app and a desktop app for exemple and keep type safety + valdiation + RQ. My maisn issue is that I didn't find a way to execute server only code in a loader. Maybe I'm wrong by doing it into the loader but if there is a better way I'm happy to use it !
sensitive-blue
sensitive-blue12mo ago
still don't get it, sorry. the loader will be executed on the server if the route is rendered using SSR if you open https://domain.com/post. but it will be executed on the client if you open https://domain.com/ and then navigate to /post e.g. by clicking a link
sensitive-blue
sensitive-blue12mo ago
GitHub
router/packages/react-router-with-query/src/index.tsx at main · Tan...
🤖 Fully typesafe Router for React (and friends) w/ built-in caching, 1st class search-param APIs, client-side cache integration and isomorphic rendering. - TanStack/router
stormy-gold
stormy-goldOP12mo ago
Oh I get it ! if you use SSR, loader will be executed only the first time on the backend? Then loader will be executed in the client along the navigation ? react-router-with-query helps that's how I'll hydrate/dehydrate the state. I just wanted to avoid to call the API on the backend when rendering the page with SSR, because I'll have to add headers for authentication etc.

Did you find this page helpful?