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
433 stars 31 forks source link

Issues with telemetry in client components #299

Open 2nPlusOne opened 3 months ago

2nPlusOne commented 3 months ago

Howdy,

My team and I have been using the experimental package for a few months now as we build up our Next.js 14 app. It's been working quite well! However, we recently started to implement telemetry, and have ran into some issues related to the package.  

What works

We followed the guide on the blog, and were able to get telemetry working for queries called from the server.

import { ApolloClient, InMemooryCache, from } from "@apollo/client";
import { registerApolloClient } from "@apollo/experimental-nextjs-app-support/rsc";

const { getClient } = registerApolloClient(() => {
  return new ApolloClient({
    cache: new InMemoryCache(),
    link: from([splitLink]),
    defaultOptions: {
      query: {
        fetchPolicy: "no-cache",
      },
    },
  }),
});

As expected, when a query is made using getClient().query, the query traces show up on the Jaeger UI, and the context progagates properly to the backend service.

What doesn't work

When making queries from the client using useQuery from the experimental package, the traces do not show up on Jaeger.

function makeClient() {
  return new NextSSRApolloClient({
    cache: new NextSSRInMemoryCache(),
    link:
      typeof window === "undefined"
        ? ApolloLink.from([
            new SSRMultipartLink({
              stripDefer: true,
            }),
            splitLink // Chooses between http and websock links (pulled from the apollo docs)
          ])
        : from([splitLink]),
  });
}
phryneas commented 3 months ago

I assume that you want to track queries happening on the server here, not what's happening in the user's browser?

useQuery doesn't make any api requests during SSR. Next.js will only let you do one render, so you'd only get a loading state in SSR, no matter if a request were made or not. If you want to make requests and have the results rendered during SSR, you'll have to use the useSuspenseQuery hook, because that one will pause React rendering until the request is done and stream the result to the browser.