dehydrate / rehydrate apollo cache
looking to fetch a query inside my loader function and then write the apollo cache to a global variable. of course, i'd rather use tanstack query in the router but i'm working on mgirating a legacy project over from nextjs. is there a way to inject a variabe into the html on the serverside? it should be easy enough to read from window.APOLLO_STATE on the client side, but i'm unsure how to write it to the page with the data from my loaders https://www.apollographql.com/docs/react/performance/server-side-rendering
Apollo GraphQL Docs
Server-side rendering
45 Replies
dependent-tan•8mo ago
the Apollo TanStack start integration is currently being developed
evident-indigoOP•8mo ago
is there a link to that anywhere? a hacky workaround i can use for now?
dependent-tan•8mo ago
cc @Lenz Weber-Tronic
xenophobic-harlequin•8mo ago
https://github.com/apollographql/apollo-client-nextjs/pull/419#issuecomment-2609678429
with README
https://github.com/apollographql/apollo-client-nextjs/blob/next/packages/tanstack-start/README.md
But there was just a PR merged in TSR that might break some things. Give it a week.
As a hacky workaround stay on exactly these versions with exactly these patches applied, together with the linked library: https://github.com/apollographql/apollo-client-nextjs/blob/1306572238ff9d9421b16164fc039d5b61f17ce9/package.json#L33-L34
xenophobic-harlequin•8mo ago
going to try setting this up now - will report back
is
@apollo/client-integration-tanstack-start
a standalone package?xenophobic-harlequin•8mo ago

xenophobic-harlequin•8mo ago
or do i just need @apollo/client at 3.12.6
@Lenz Weber-Tronic
running into some issues downloading the patched dependencies, might be missing something stupid though
does this add an apollo provider internally? pretty cool set up, seems really flex if it's all hydrated and available through router context
xenophobic-harlequin•8mo ago
Yeah seeems the build is broken somehow.. should be available at https://pkg.pr.new/apollographql/apollo-client-nextjs/@apollo/client-integration-tanstack-start@419 but is not right now.
I'll take a look a bit later
And yeah, that does all the setup of the provider etc for you.
xenophobic-harlequin•8mo ago
beautiful - can you let me know when the build is working @Lenz Weber-Tronic ?
happy to set it up and provide feedback
xenophobic-harlequin•8mo ago
@tyler I won't get to fixing the build on that branch right now, but I looked around, and this one should do the trick for now:
xenophobic-harlequin•8mo ago
@tyler this PR is now compatible with TSR 1.99: https://github.com/apollographql/apollo-client-nextjs/pull/422
You can install it like this:
xenophobic-harlequin•8mo ago
beautiful
i'll try it out today
@Lenz Weber-Tronic setting this up now - is there a way to access the apolloClient from a serverFn
xenophobic-harlequin•8mo ago
I'm not sure if those exist within or independently of the router - if they exist within, you should be able to access it on the router context
xenophobic-harlequin•8mo ago
is this the error you mentioned? Error in renderToPipeableStream: Error: useTransportValue must be used within a streaming-specific ApolloProvider
"@tanstack/react-router": "^1.98.3",
"@tanstack/start": "^1.98.3",
@Lenz Weber-Tronic do i need downgrade to the patched dependencies up there?
xenophobic-harlequin•8mo ago
No, upgrade. You need 1.99.4 at lat
1.99 completely changed the streaming so I had to rewrite a lot, it won't work with older versions now
(npm should also tell you)
but as a result you don't need to patch anything
xenophobic-harlequin•8mo ago
got it - trying again now
seems to be working !
rival-black•8mo ago
Can I hijack here and ask if any of yall here have hit this?
EDIT: Ugh sorry. It was a bad regex on my side trying to fix
@apollo/client
importing CJS.
xenophobic-harlequin•7mo ago
Also sharing that here - first alpha has shipped: https://www.npmjs.com/package/@apollo/client-integration-tanstack-start
npm
@apollo/client-integration-tanstack-start
This package provides integrations between Apollo Client and TanStack Start to support modern streaming SSR.. Latest version: 0.12.0-alpha.0, last published: 19 hours ago. Start using @apollo/client-integration-tanstack-start in your project by running
npm i @apollo/client-integration-tanstack-start
. There are no other projects in the npm regi...rival-black•7mo ago
Huge amount of work @Lenz Weber-Tronic thank you.
evident-indigoOP•7mo ago
hey @Lenz Weber-Tronic , apologies if this is the wrong place for this. is there a way to prefetch a query in the route loader and still read it using useSuspenseQuery in the component, and ensure that if it's cahced (via the prefetch) it won't trigger another fetch in the child
the example in the docs don't mention doing this, but i'd like to be able to prefetch a query in my route loader, and then read it in the component without having to pass props or read from useLoaderData in the child component.

xenophobic-harlequin•7mo ago
It should work, but it's more "loose" and i might depend on timing circumstances if a second network request happens or not. I'd go either way - only in the component (which will also prevent a request in the browser, just like the loader) or in the loader with
useReadQuery
.
You might also want to just look into useSuspenseFragment
, which shipped today with Apollo Client 3.13.evident-indigoOP•7mo ago
if i use a regular useQuery + fetchPolicy:
cache-first
will that also read from the hydrated apollo cache if i fetch inside a loader?
@Lenz Weber-Tronicxenophobic-harlequin•7mo ago
Yes, but it wouldn't SSR, as non-suspenseful hooks cannot "pause" a render in SSR and wait for the data to come in to render it.
I would generally recommend sticking to suspenseful hooks.
evident-indigoOP•7mo ago
yeah we just have some old code that may be annoying to migrate
xenophobic-harlequin•7mo ago
If you're okay with a loading state during SSR that should work
evident-indigoOP•7mo ago
i'm not entirely sure the difference, if i streamed using the suspenseful hook, wouldn't it also render the suspense fallback during ssr? or is there a chance it could have the data even if we don't await it in the loader
xenophobic-harlequin•7mo ago
It will stream the suspense fallback, but then also the rendered component.
That's the magic of streaming SSR.
Without suspense it only streams "loading" and then renders content in the client.
The true magic is in the case of a search enging - it doesn't stream the suspense fallback, but waits for content
evident-indigoOP•7mo ago
don't you still need client side JS to update the DOM if the initial HTML response comes down before the suspensed data is ready
xenophobic-harlequin•7mo ago
yes, but that streams as part of the HTML in script tags, it can already render that stuff in before the potentially very big .js files are parsed and executed
evident-indigoOP•7mo ago
i was thinking that. so it is brilliant. and it just renders the suspense fallback if the user has JS disabled?
xenophobic-harlequin•7mo ago
yap
unless they're a search engine, then it just takes longer until the final content comes in
evident-indigoOP•7mo ago
react does that automatically?
xenophobic-harlequin•7mo ago
most frameworks do, react just provides the building blocks
https://github.com/TanStack/router/blob/b5d14325b3387c08be34181c4e070278424a1f69/packages/start-server/src/defaultStreamHandler.tsx#L32-L33
Here it is in TanStack Start
rival-black•7mo ago
This stuff is magic ✨
dependent-tan•7mo ago
mostly "black magic" TBH 😄
rival-black•7mo ago
Based on the src I've scrolled through in both of these repos that is 💯 😆
@Lenz Weber-Tronic is
.toPromise()
going away? how can I wait for the GQL data before rendering SSR? Or am I thinking about this wrong?xenophobic-harlequin•7mo ago
Unfortunately, functions are not serializable and you are passing that object over the wire, so unless you are using it client-side only without SSR, it's going away.
That said, I can't think of a really good use for it, given that you can just suspend a full page.
rival-black•7mo ago
Ok that helps. Struggling here learning both TanStack (router & start) & suspense at the same time lol
xenophobic-harlequin•7mo ago
@Lenz Weber-Tronic we're getting this error when passing in preload query ref created in the loader
Error in renderToPipeableStream: Invariant Violation: Expected a QueryRef object, but got something else instead.
worth noting that it works on the client, but this error is logged on the serverevident-indigoOP•7mo ago
i imagine we have some mismatch in our node_modules or it's trying to compare the symbol from an ESM build and an identical CJS build and that's why the equality check fails.
xenophobic-harlequin•7mo ago
Yeah, I'm aware that this can happen - I'm currently on a very big ticket, but once I'm done with that I'll look into this
@tyler @matthewsomethin could you update Apollo Client to
3.13.2
which was just released and see if that fixes the problem?evident-indigoOP•7mo ago
let me try. we just updated to 3.13.1 a few hours ago haha
that didn’t work @Lenz Weber-Tronic
xenophobic-harlequin•6mo ago
Dang :/ Could you provide me with a reproduction of this?
I just released a new version of the support package, could you report back if that improves anything? 🙂
evident-indigoOP•6mo ago
of the tanstack client?
xenophobic-harlequin•6mo ago
@apollo/client-integration-tanstack-start@0.12.0-alpha.3 - no direct changes in that one, but some changes in the core it relies on (@apollo/client-react-streaming@0.12.0-alpha.3) that might be relevant for this problem