Solid +Astro SSR + Data Fetching on hydration
Hi! I working on an Astro site with Solid and I am having trouble getting Solid to fetch data.
I would like to only fetch the component has been hydrated, but can't seem to get it to work.
I am trying to detect if we are on the client by looking if window is defined.
The console logs are correct, but the fetch is never triggered.
What am I doing wrong? Please keep in mind this is the 1st time I am using Solid
3 Replies
A couple things:
1.
solid-js/web
actually exports an isServer
, which you can use to check if you’re server rendering. So no need to define it yourself!
2. Your isSSR
signal (and Solid’s isServer
for that matter) isn’t really reactive. Even though the value technically “changes” when it goes from the server to the client, the server is a separate reactive context from the client. So the change in value won’t be detected on hydration and the resource won’t run again. So it being a signal doesn’t actually do anything here to refetch the resource.
A signal from createSignal
only triggers effects if its setter is called and changes the value. Otherwise it won’t do anything. Since you’re not creating or using a setIsSSR
(because why would you for this?), it won’t trigger the refetch.
Also, Astro runs your Solid components inside a Suspense
block, which (I believe) means that resources will all run on SSR and not on hydration (but can still be re-run client-side). This behavior in Astro is relatively new though so I might have a few things wrong
I would recommend changing the isSSR to Solid’s isServer, or using Vite’s import.meta.env.SSR, and just check it directly in your fetchCurrent
function rather than passing it in as a signal (though either way is fine! It’s just not reactive)
Then I’d take the refetch
method that createResource
returns, and call it inside an onMount
or createEffect
- it’s the same either way, I just like onMount if I know I’m only running something once.
Alternatively, you could keep the code you have and just try setting isSSR
again in an onMount
function or other event handler, which should lead to a refetch as well.
ALTERNATIVE alternatively, if you don’t need this component to render on the server at all, because the markup depends on the data you’re fetching, you could use a client:only=“solid-js”
on the Solid component in the Astro fileThank you @snailyluke!
isServer
and refetch
work great! I needed to also Suspense
in my component instead of Show/Match/Switch
, but I think the code seems cleaner with the suspense.
Thanks again! 😄Oh yeah for sure, suspense is the way to go there too!
No problem 😊