How to integrate Apollo Client into Solid Start with SSR?
I got Apollo working fine with my own custom functions/provider (solid-apollo hasn't been touched in 3 years and the author has made no attempt to fix anything, and I don't believe it supported reactivity in the variables anyways, so variables needs to be a function call in createQuery), but I'm having trouble getting it to properly work with SSR. The client on the server doesn't talk to the client on the browser and I was trying to go through the server rendering docs https://www.apollographql.com/docs/react/performance/server-side-rendering but you cannot use some of this code as it's React specific (getDataFromTree for example), so does anyone know how to actually integrate the two? I stashed all the changes that I was trying to do, so this is pre any of that.
Apollo GraphQL Docs
Server-side rendering
![No description](https://cdn.answeroverflow.com/1332422889734934601/Screenshot_2025-01-24_at_10.51.18_AM.png)
![No description](https://cdn.answeroverflow.com/1332422890234052658/Screenshot_2025-01-24_at_10.51.45_AM.png)
![No description](https://cdn.answeroverflow.com/1332422890674585690/Screenshot_2025-01-24_at_10.52.01_AM.png)
![No description](https://cdn.answeroverflow.com/1332422891140026510/Screenshot_2025-01-24_at_10.52.13_AM.png)
![No description](https://cdn.answeroverflow.com/1332422891660378164/Screenshot_2025-01-24_at_10.52.23_AM.png)
![No description](https://cdn.answeroverflow.com/1332422892067229847/Screenshot_2025-01-24_at_10.52.31_AM.png)
16 Replies
I can also make a codesandbox template or whatever so someone is not starting from zero if anyone would like.
Any ideas here @REEEEE @peerreynders ? You essentially need some sort of equivalent to getDataFromTree or react-ssr-prepass as far as I'm aware to call all the queries first and use that to load state for the cache, but I have no idea where to get that for solid (or if I have to write one myself) and then how to integrate that properly.
I've had no exposure to Apollo. Though on the surface it looks as if the SSR integration would be quite an undertaking.
Well in React it's not that much work, I just don't see an equivalent to getDataFromTree
Basically this creates a ton of weird issues where the cache is not aware of itself
getDataFromTree
is the React integration that the Apollo team has already supplied. Basically you'd need an equivalent strategy to know when all the queries necessary for the SSR render have completed; then there is the issue of inserting __APOLLO_STATE__
into the HTML without interfering with Solid's hydration process.Yes I'm aware. An issue I'm seeing is seemingly you cannot make createHandler's passed in function async or it breaks?
You get
const first = html.indexOf(marker);
^
TypeError: Cannot read properties of undefined (reading 'indexOf')
doing nothing but changing it to createHandler(async () => {...etc}). mode: 'async' inside StartServer doesn't seem to change that fact.
Because I had ChatGPT help me with a function that seemingly can replicate it but I can't get past that point
So I switched this to urql because it seemed slightly easier to integrate but still same issue - does anyone from the start team know how to do this? @Brendonovich (I can't seem to @ that role). Re urql I'd have to add an equivalent to the prepass function but StartServer doesn't seemingly accept that being async. https://commerce.nearform.com/open-source/urql/docs/advanced/server-side-rendering/
Relevant updated code on app.tsx and entry-server.tsx respectively.
![No description](https://cdn.answeroverflow.com/1333288576179507211/Screenshot_2025-01-26_at_8.12.20_PM.png)
![No description](https://cdn.answeroverflow.com/1333317806736932926/Screenshot_2025-01-26_at_10.08.51_PM.png)
I'd have to spend some more time figuring this out, solid doesn't really do prepass like how react does
Gotcha, well I can send you anything else you'd need.
In fact, I'll put together a basic thing with the Rick and Morty API with the relevant code bits so you wouldn't have to start from zero.
Side note - the default Code Sandbox template for Solid Start doesn't work, you may want to reach out to someone there about it.
"Error when evaluating SSR module $vinxi/handler/ssr:
|- Error: Client-only API called on the server side. Run client-only code in onMount, or conditionally run client-only component with <Show>."
It doesn't look obviously wrong though.
Edit: Upgrading all dependencies worked though.
https://codesandbox.io/p/devbox/solid-start-urql-dnjcly this is what I have so far. Not the best example since you can't mutate that API but will do for this I guess.
if you're going to serialize yourself anyway, i don't think you want/need to use
createResource
as it's also gonna serialize itself. so in the final output, you have
1. html generated using the data
2. serialized resource data
3. manually serialized data
you still need createResource
to integrate with Suspense though so i guess you just don't use it for data
i don't know much about graphql so i better study it first 😆Well an alternative to our solution is that literally we just don't use ssr, however I still get issues like this on dev - https://github.com/solidjs/solid-start/issues/519, which is clearly not fixed. We have zero need for SEO etc, this is purely a dashboard view for our clients.
GitHub
Issues · solidjs/solid-start
SolidStart, the Solid app framework. Contribute to solidjs/solid-start development by creating an account on GitHub.
Doesn't really solve that I'm not sure how you would do this properly in SolidStart, but it is a workaround
Also still seems to do an initial render on dev from the server?
just to confirm, say i have a list query
[book0, book1]
and then another query for book0
, does the client dedupe the item query and use the list result? apollo client has queryDeduplication
true by default but i'm not sure if it's doing anythingWell the issue isn't for multiple queries. It's that the initial data is being gotten on the server, so the client side cache is completely unaware of it when you then try to update the cache after a mutation.
So like we generate a list of things, which should remove the list on the sidebar completely and replace them with the new list, but that's not the top level query for the sidebar. But the client side cache is completely unaware that those things exist because the mutation is on the client but the data was initially gotten on the server side.
And there is no way to easily update the client side cache because that's normally done with either getDataFromTree (in apollo on React) or prepass() (in urql on React)
Basically you're grabbing all the queries ahead of time and using that to hydrate the initial state, which you inject into the window for the client side cache to set its initial values with
to answer this myself, even if everything is working, apollo client doesn't do this, it needs to query once