apollo-client-nextjs icon indicating copy to clipboard operation
apollo-client-nextjs copied to clipboard

SSR not working properly

Open juanstiza opened this issue 7 months ago • 7 comments

Hi all!

I'm having a strange issue while setting up SSR. I haven't found this problem being described anywhere else. Any help will be appreciated!

What I expect:

Loading the page in the browser without javascript should render the correct content.

What I get:

The page renders only the fallback. If I load the page again without restarting the server, I can see the content.

Dependencies

react: ^18, installed: 18.2.0 @apollo/client: ^3.10.8, installed: 3.10.8 @apollo/experimental-nextjs-app-support: ^0.11.2, installed: 0.11.2 graphql: ^16.9.0, installed: 16.9.0

Setup

Apollo provider

// ApolloPrpovider.tsx
'use client';
import { ApolloLink, HttpLink } from '@apollo/client';
import {
  ApolloClient,
  ApolloNextAppProvider,
  InMemoryCache,
  SSRMultipartLink,
} from '@apollo/experimental-nextjs-app-support';
import React from 'react';

function makeClient() {
  const httpLink = new HttpLink({
    uri: 'https://myapi.com/graphql',
  });

  return new ApolloClient({
    cache: new InMemoryCache(),
    ssrMode: true,
    link:
      typeof window === 'undefined'
        ? ApolloLink.from([
            new SSRMultipartLink({
              stripDefer: true,
            }),
            httpLink,
          ])
        : httpLink,
  });
}

export function ApolloWrapper({ children }: React.PropsWithChildren) {
  return (
    <ApolloNextAppProvider makeClient={makeClient}>
      {children}
    </ApolloNextAppProvider>
  );
}

Page component

// src/app/product/page.tsx
import React from 'react';
import { MyPage } from '@/app/components/ProductPage';

export default function Page({ params }: { params: { slug: string } }) {
  return <ProductPage urlSlug={params.slug} />;
}

Content component

// src/components/ProductPage.tsx
import React, { Suspense } from 'react';
import Content from '@/app/components/Product';

export const ProductPage: React.FC<{
  urlSlug: string;
}> = ({ urlSlug }) => {
  return (
    <Suspense fallback={'Loading...'}>
      <Product urlSlug={urlSlug} />
    </Suspense>
  );
};

Product component, it should render the product's title.

// src/component/Product.tsx
'use client';
import { useSuspenseQuery } from '@apollo/client';
import query from '@/feature/product.query';

export const dynamic = 'force-dynamic';

export default function Product({
  urlSlug,
}: {
  urlSlug: string;
}) {
  const { data, error } = useSuspenseQuery(query, {
    variables: {
      slug: urlSlug,
    },
  });
  const product = data.product;

  return product.title;
}

juanstiza avatar Jul 19 '24 16:07 juanstiza