apollographql / apollo-client-nextjs

Apollo Client support for the Next.js App Router
https://www.npmjs.com/package/@apollo/experimental-nextjs-app-support
MIT License
352 stars 25 forks source link

Remix #248

Open phryneas opened 1 month ago

phryneas commented 1 month ago

First the good news: streaming SSR with the suspense hooks and Remix works.

All the setup for that is in this diff: https://github.com/phryneas/remix-apollo-stream-example/commit/bc43efe4a3f53d0672217cc33dfb20523af4d9c3

That said, supporting loaders is another beast. I'll add my thoughts in this thread.

phryneas commented 1 month ago

Thoughts on Loaders

Loaders run independently of React.

As a result, our current "inject into the stream" approach won't work - we have no way of sharing an AC instance reliably between handleRequest and loader, and oftentimes there's not even a handleRequest

=> each loader should create their own instance of Apollo Client and createQueryPreloader.

const loader = () => {
  const preload = createQueryPreloader(makeClient())

  const result1 = preload(query1)
  const result2 = preload(query2)

  return defer({
    result1,
    result2
  })
}

Now, right now preload creates a queryRef - that's hardly feasible in this case, since it can't be transported over the wire.

So we probably need to wrap createQueryPreloader (https://github.com/apollographql/apollo-client/pull/11719) to have a completely different functionality in SSR.

It could create a value like

{
  query,
  variables,
  resultPromise
}

which would then be picked up by an (also wrapped) useReadQuery that would simulate an ongoing request (simulating the request start sooner would be great, but is probably not possible).

Currently, the defer implementation doesn't support promises that are not on the top level yet.

We'd probably need buy-in from the Remix team here to be able to make according changes on their side - once we have fleshed out this story more.