apollographql/apollo-client-nextjs

Can't create a client per page

JCB-K opened this issue · 7 comments

I'm not sure if this is a bug or a user error, but I can't wrap 2 different pages in 2 different GraphQL providers with respective clients, as makeClient is not called a subsequent time after navigating from page 1 to 2.

I've created a sandbox here that demonstrates the problem: https://codesandbox.io/p/devbox/kind-tristan-jnk964

  • I've wrapped 2 different pages (A and B) both in a ApolloNextAppProvider, with their own client
  • rendering one page correctly provides the client to the React context
  • browsing to to other page I'd expect to receive the other client, but it's still the first one
  • it seems that makeClient is never called, and that the original client is cached somehow

Is this a bug, or do I misunderstand how the provider should work?

You should only ever have one ApolloClient instance - and one provider - in your application.

This is a restriction we have here because your page will run in SSR, and if you had multiple providers we wouldn't know which data should be rehydrated with which client instance.
But apart from that, it's also generally a good rule of thumb ;)

Just place your NextApolloProvider in your root layout. You don't need one per page.

@phryneas In that case, how would I switch client between pages? The layout doesn't re-render on page navigation.

You should never switch the client. Why do you want to do that?

I have 2 applications within the same Next.js app that communicate with different graphql servers. As of now I don't have the control to merge these into a single GQL endpoint.

Ah, that's indeed one of the very rare cases where that might make sense.

You could call resetApolloClientSingletons when your page renders, that would clear any old globally stored ApolloClient instance.

import { resetApolloClientSingletons } from "@apollo/experimental-nextjs-app-support";

That worked great, thanks! For future reference for those reading this issue: you want call resetApolloClientSingletons whenever the client changes. In my case I found it most natural to do so in ApolloWrapper:

export function ApolloWrapper({
  children,
  client,
}: React.PropsWithChildren<{ client: "a" | "b" }>) {
  React.useEffect(() => {
    resetApolloClientSingletons();
  }, [client]);
  return (
    <ApolloNextAppProvider makeClient={getMakeClient(client)}>
      {children}
    </ApolloNextAppProvider>
  );
}

Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Client usage and allow us to serve you better.