#Using Relay in combination with Remix

1 messages · Page 1 of 1 (latest)

red badge
#

Hi everyone,

I have been looking at Remix for quite some time now and I would like to give it a try.

I would like to use Remix in combination with Relay to interact with a GraphQL endpoint and my ideal use case:

  • Fetch a few 'main' queries SSR (like an user profile query which is for SEO).
  • Fetch most other queries client side since those are not needed to be server sided.

I am wondering if it is possible to use Relay in combination with Remix and if there are any good SSR templates/boilerplates for it.

I saw something about clientLoader and a normal loader but I am not quite sure if I am able to use the Relay hooks inside of those. Very new to this environment so hope someone is able to help me out.

Thanks a lot! I'd appreciate it.

gusty spear
#

since Relay requests compiler integration it may be possible with the Vite plugin of Remix, after that you will not use Remix loaders/actions, or only use them to trigger your queries

red badge
gusty spear
#

I never used Relay, so I don't know how to do it

red badge
#

Ah no worries, I’ll try to take a look! Thank you anyways

gusty spear
#

but I think you should write fragments per component, use the routes to group fragments of every component inside, then trigger those queries from inside loader and clientLoader, the first for SSR and second for client-side navigations

red badge
#

I see. By default Relay has a useLazyLoadQuery hook that you would use on component level, but I assume that it’s not possible to use hooks inside of this clientLoader function?

#

Or can I maybe use that hook instead of the clientLoader, in my component. Or would that also make a server side request

gusty spear
#

you can't use hooks inside clientLoader

#

the clientLoader and clientAction functions run outside React

red badge
#

Hmmm I have to see how I’d use Relay without that hook.

rare cypress
#

The dataStrategy config we're adding to React Router for single fetch is going to be what unlocks this for RR. Not 100% sure if that'll be exposed to Remix but I think we're leaning towards yes

#

Right now, RR calls all loaders in parallel. dataStrategy will give you full control over that - when loaders need to be run, you can provide an implementation that basically gets handed the matches and you are responsible for calling the loaders and returning results accordingly. This could be in parallel, sequentially, via a single fetch, etc.

#

So you could stick a GQL fragment on each route.handle, combine them in the function and make one API call, and then extract individual results from the API response per-match and return them.

red badge
#

That does sound promising! Looking forward to that

red badge
#

Quick question. I am trying to see how the data layer of Remix works so I created a quick example project with Vite and react-query and trying the following.

This works great and this is just like normal React, runs the query client side and I see the request in my network tab, as expected.

#

Then I tried to switch over to Suspense, so I don't have to use the isLoading boolean:

#

But this makes the request run through SSR for some reason.

#

Is that how Suspense works?

#

I am not sure maybe I am wrong

#

Without the 'Suspense version', I only saw this log in my browser.

rare cypress
#

Remix does it's data loading through route loader functions which are decoupled from rendering. You can use a suspense-driven skeleton UI via defer

red badge
#

Hmm I see. Right now I am not using any loader functions so I was just trying to see how my normal client-side calls would work

#

And I wanted to use Suspense just for the loading state

#

But apparently that makes it run on the server

rare cypress
#

Do you want SSR at all?

red badge
#

I do but only for a few queries

#

In this case I was just testing the non-SSR variant, which will be most of my queries

rare cypress
#

I think you'll need to get the prefetching working to get useSuspenseQuery wired up with any type of SSR

red badge
#

I see! With this SPA mode, can I still somehow run certain queries on the server or do I have to find a way to implement that?

#

Right now I am using react-query with a test API to see how the data layer works before I try to implement Relay.

But the majority of my queries will be ran client side and only important SEO related queries like user profiles etc, will be done on SSR.

rare cypress
#

IMO, SPA Mode should make it easier to iron out the kinks and get a working SPA while "thinking in Remix". Then you can remove the unstable_ssr flag and everything should still work, at which point you can sprinkle in server loader's whereever you'd like

red badge
#

I'll have a look, thank you! I appreciate it

red badge
#

Hey guys,

It's going pretty well with getting Relay to work in Remix. However, I am trying to get preloaded queries to work aswell, but unfortunately no luck and I am not quite sure why.

Preloaded queries from Relay: https://relay.dev/docs/api-reference/use-preloaded-query/

Basically Relay wants you to pass the result from loadQuery as the second parameter to a usePreloadedQuery hook. In the Relay documentation they are saying that this is provided by the router or something so I tried to pass this from my loader like in my screenshot. I expected this to work but this results into the following error in the console:

usePreloadedQuery was passed a preloaded query that was created with a different environment than the one that is currently in context. In the future, this will become a hard error

And then I found this GitHub discussion with a similar problem for Next.js: https://github.com/vercel/next.js/discussions/33680
Apparently it's not an issue with passing the wrong environment or anything, since I am using the exact same environment for the RelayEnvironmentProvider.

I am not quite sure if this is possible since the loader does run on the server but I am not quite sure how I should make this work with Relay.

If someone is able to help me out, I'd really appreciate it.

I also tried to use clientLoader instead, I feel like this does somewhat work but this gets rid of all SSR for this preloaded query.

Not sure how to fix this unfortunately, I'm also fairly new with Relay and Remix so I'm trying to figure it out.

rare cypress
#

yeah that seems like the right approach to me. Load the query in a loader, grab the result from useLoaderData, and use it in usePreloadedQuery. Is that error throwing on the server or in the browser during hydration? If the browser, then my hunch is that whatever charactersRef is is maybe not json serializable so it's not making it up correctly through the Remix hydration process

#

If it's throwing on the server then that's odd and I'd probably want to dig into the relat ource to see what type of comparison is triggering that