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
435 stars 32 forks source link

Is `ssrMode: true` in ApolloClient not needed when using SSR in client components? #350

Closed anthonyhoegberg closed 1 week ago

anthonyhoegberg commented 3 weeks ago

In the readme under In Client Components and streaming SSR section this following code is provided

"use client";
// ^ this file needs the "use client" pragma

import { HttpLink } from "@apollo/client";
import {
  ApolloNextAppProvider,
  ApolloClient,
  InMemoryCache,
} from "@apollo/experimental-nextjs-app-support";

// have a function to create a client for you
function makeClient() {
  const httpLink = new HttpLink({
    // this needs to be an absolute url, as relative urls cannot be used in SSR
    uri: "https://example.com/api/graphql",
    // you can disable result caching here if you want to
    // (this does not work if you are rendering your page with `export const dynamic = "force-static"`)
    fetchOptions: { cache: "no-store" },
    // you can override the default `fetchOptions` on a per query basis
    // via the `context` property on the options passed as a second argument
    // to an Apollo Client data fetching hook, e.g.:
    // const { data } = useSuspenseQuery(MY_QUERY, { context: { fetchOptions: { cache: "force-cache" }}});
  });

  // use the `ApolloClient` from "@apollo/experimental-nextjs-app-support"
  return new ApolloClient({
    // use the `InMemoryCache` from "@apollo/experimental-nextjs-app-support"
    cache: new InMemoryCache(),
    link: httpLink,
  });
}

// you need to create a component to wrap your app in
export function ApolloWrapper({ children }: React.PropsWithChildren) {
  return (
    <ApolloNextAppProvider makeClient={makeClient}>
      {children}
    </ApolloNextAppProvider>
  );
}

Inside here:

  return new ApolloClient({
    // use the `InMemoryCache` from "@apollo/experimental-nextjs-app-support"
    cache: new InMemoryCache(),
    link: httpLink,
  });

is ssrMode: true, necessary here or is it handled internally by @apollo/experimental-nextjs-app-support where we imported it from?

phryneas commented 3 weeks ago

It's not needed at all: ssrMode only works with single-hydration-pass SSR, but Next.js is using streaming SSR, which is a completely different mechanism . It's essentially a legacy option you only need when you do renderToString so please don't use it in this context :)

anthonyhoegberg commented 3 weeks ago

I have a different question, i just got done setting up a new project using makeClient code etc, but in my browser inspector i can see the browser making requests to the graphql server directly, shouldn't the requests be from the server to graphql server?

phryneas commented 3 weeks ago

SSR of Client Components only happens on initial page load. Every request you start after that is purely in the browser.

anthonyhoegberg commented 3 weeks ago

SSR of Client Components only happens on initial page load. Every request you start after that is purely in the browser.

I think this should be a bit more clear in the docs or readme, that every request after that happens in the browser. It wouldn't really be SSR if requests after are made from the browser.

phryneas commented 3 weeks ago

That's how Next.js works, that has nothing to do with this library.

Next.js executes RSC on the server and does a single SSR pass of Client Components on page load, but after that executes Client Components purely in the browser.

github-actions[bot] commented 1 week ago

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.