Next.js developers faced with GraphQL Apollo Client insistence on utilizing cache

Our Apollo Client implementation in Next.js (v14.2.5) SSR using the getClient() method is currently facing an issue where cached data is not being updated with the new data from the server.

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

export const { getClient } = registerApolloClient(() => {
  return new ApolloClient({
    link: new HttpLink({
      uri: `${process.env.NEXT_PUBLIC_ADMIN_BASE_URI}/api/graphql`,
    }),
    defaultOptions: {
      query: {
        fetchPolicy: "network-only",
      },
    },
    ssrMode: true,
    ssrForceFetchDelay: 1,
    cache: new InMemoryCache({
      resultCaching: false,
      typePolicies: {
        Yachts: {
          merge: true,
          fields: {
            keyFeatures: {
              merge(existing = [], incoming: any[], { readField }) {
                const merged: any[] = existing ? existing.slice(0) : [];
                const featureNameToIndex: Record<string, number> = {};

                existing.forEach((feature: any, index: any) => {
                  const name = readField<string>("name", feature);
                  if (name) {
                    featureNameToIndex[name] = index;
                  }
                });

                incoming.forEach((feature) => {
                  const name = readField<string>("name", feature);
                  if (name) {
                    const index = featureNameToIndex[name];
                    if (typeof index === "number") {
                      merged[index] = {
                        ...merged[index],
                        ...feature,
                      };
                    } else {
                      featureNameToIndex[name] = merged.length;
                      merged.push(feature);
                    }
                  }
                });

                return merged;
              },
            },
          },
        },
      },
    }),
  });
});

Despite confirming that the server data is correctly updated (verified with Postman), queries to our API are returning stale data. For example, the query below may return outdated information:

"use server";

import IBrokerino from "@/types/brokerino";
import { getClient } from "@/apollo";
import { gql } from "@apollo/client";

export const fetchBrokerinos = async (): Promise<IBrokerino[]> => {
  const client = getClient();
  const { data } = await client.query({
    query: gql`
      query Users {
        Users(where: { displayOnWebsite: { equals: true } }) {
          docs {
            name
            picture {
              alt
              sizes {
                fhd {
                  url
                  width
                  height
                }
              }
            }
            phones {
              prefix
              number
            }
            langs
            email
            position
          }
        }
      }
    `,
  });
  return data.Users.docs;
};

Various attempts to resolve this issue, such as setting individual fetch-policy to no-cache for each query, have not been successful.

Our goal is to eliminate caching altogether to ensure fresh data is fetched from the API on every website load. We have explored other client options and tried disabling caching in Next.js without any improvements.

Below is an example of how we are executing the server-side query in page.tsx:

import Hero from "@/components/company/hero";
import Bar from "@/components/nav/bar";
import dynamic from "next/dynamic";
import { fetchBrokerinos } from "@/actions/brokerino";

const View = dynamic(() => import("@/components/view"));
const Footer = dynamic(() => import("@/components/footer"));
const Story = dynamic(() => import("@/components/company/story"));
const Accordion = dynamic(() => import("@/components/company/accordion"));
const Team = dynamic(() => import("@/components/company/team"));
const Lifestyle = dynamic(() => import("@/components/company/lifestyle"));

const Company = async () => {
  return (
    <main className="w-full flex flex-col justify-start items-center">
      <Bar dynamicColor={-1} />
      <View />
      <Hero />
      <Story />
      <Accordion />
      <Team brokerinos={await fetchBrokerinos()} />
      <Lifestyle />
      <Footer />
    </main>
  );
};

export default Company;

Answer â„–1

This isn't caused by Apollo Client caching but rather by Next.js caching the outgoing fetch calls.

To resolve this issue, refer to the Next.js documentation on fetch caching

To stop this caching behavior in Next.js, you need to add

fetchOptions: { cache: "no-store" }
. Here's an example from the README of the
@apollo/experimental-nextjs-app-support
package:

export const { getClient, query, PreloadQuery } = registerApolloClient(() => {
  return new ApolloClient({
    cache: new InMemoryCache(),
    link: new HttpLink({
      uri: "http://example.com/api/graphql",
      fetchOptions: { cache: "no-store" },
    }),
  });
});

Remove the following lines:

    ssrMode: true,
    ssrForceFetchDelay: 1,

They don't have any impact on streaming SSR. You can also remove resultCaching: false and possibly other unnecessary options.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering a TS2307 error while trying to import external modules into a TypeScript file

I recently added a new module using npm and now I'm trying to use it in my typescript file. npm install marker-animate-unobtrusive --save import SlidingMarker = require('marker-animate-unobtrusive'); Unfortunately, when I try to access th ...

The attribute 'X' is not found in the type 'HTMLAttributes<HTMLDivElement>'.ts(2322)

Encountered an issue using JSX sample code in TSX, resulting in the following error: (property) use:sortable: true Type '{ children: any; "use:sortable": true; class: string; classList: { "opacity-25": boolean; "transition-tr ...

Display a popup notification when clicking in Angular 2

Can anyone help me with displaying a popup message when I click on the select button that says "you have selected this event"? I am using Angular 2. <button type="button" class="button event-buttons" [disabled]="!owned" style=""(click)="eventSet()"&g ...

The Socket.io socket listener in the Next.js API is failing to refresh and update properly

I am working on a Next.js project that includes a basic implementation of Socket.IO. Check out the code snippet below: // pages/index.tsx let socket: Socket; const Home: NextPage = () => { useEffect(() => { async function initializeSocket() { ...

Caution: Discrepancy found in Prop className between server and client rendering in a React SSR application

Currently, I am working on integrating a collapsible sidebar into my React application that relies on a value stored in the local storage. The intended behavior is for the sidebar to have the className of "inline" if the value is true, and "hidden" if the ...

Formatting Time in Angular 2 Using Typescript

Upon reviewing my date source, I found the following: TimeR ="2017-02-17 19:50:11 UTC"; Within the HTML file, I implemented this code snippet <span class="text-lg">{{TimeR | date: 'hh:mm'}}</span> The current output displays the t ...

Guide on accessing APIs for individual elements in an array

Currently utilizing Next.js / React.js and making use of this API to retrieve information about a specific country. Within the response, there exists an array called borders, as shown below: borders: [ "CAN", "MEX", ], There is ...

Ways to resolve issue with a build script that is missing when deploying Cypress in GitHub Actions

I recently attempted to implement a GitHub action to run Cypress tests on my app. Here is the configuration of my workflow file: name: Cypress Tests on: [push] jobs: cypress-run: runs-on: ubuntu-latest defaults: run: working-dire ...

What are the steps to utilize the feature of "nprogress"?

After successfully installing npm install nprogress in my project, I encountered an issue when trying to refresh the page - the console displayed the following message: hot-dev-client.js:182 [Fast Refresh] done hot-dev-client.js:196 [Fast Refresh] rebuildi ...

Tips for sending props, state, or arguments to a TypeScript React component

Hey there, total newbie here... I'm currently working on a school project and I've hit a bit of a roadblock... I'm attempting to pass some props from one component to another, but for some reason, it's not working properly. The goal ...

Is it feasible to create a personalized shopping cart using React with Snipcart?

Currently, I am in the process of developing a new website using Next and have integrated Snipcart. The Snipcart UI incorporates Vue.js along with embedded images and an external CSS file, which unfortunately contribute to a significant increase in the pag ...

Troubleshooting Next.js app creation in Windows WSL

After setting up WSL 2 on my Windows system for app development, I attempted to create a next.js app using 'npx create-next-app@latest' in the directory '/home/lucastso/dev'. Surprisingly, my terminal displayed the following prompts: â ...

Dynamically incorporating validation to an ngModel input

Utilizing NgForm, I dynamically added a validator to the input field. In my first example, everything works perfectly when I use the button setValidation to validate the input. However, in the second example where I add formGroup, I encounter an error whe ...

Is it possible to configure modules in Nuxt3 without the use of the createApp() function by utilizing the

Is there a Vue function available that can achieve the same effect as app.use(UseWagmiPlugin, config); in the code snippet below, without having to import './app.vue' and use createApp()? (For more information, refer to the documentation on GitHu ...

Having trouble transferring information between two components in Angular version 14

Having recently delved into the world of Angular, I'm grappling with the challenge of passing data from a parent component to a child component. On my product listing page, clicking on a product should route to the product detail page, but I can' ...

Utilizing ngx-bootstrap alongside Angular 4 in a server-side rendering environment

After setting up ngx-bootstrap and Angular-CLI 1.0.1 for universal rendering as per guidance from Roberto Auler's Post, I encountered an issue. I made sure to include the path to the Bootstrap file in angular-cli.json styles. "styles": [ ". ...

Most effective method for initiating model class attributes

Is there a more efficient way to initialize model classes without explicitly defining each member as undefined? The original concept was to be able to simply use super(data); in extended classes. class Model { construct(data: any) { Object.ke ...

Creating a unique custom selector with TypeScript that supports both Nodelist and Element types

I am looking to create a custom find selector instead of relying on standard javascript querySelector tags. To achieve this, I have extended the Element type with my own function called addClass(). However, I encountered an issue where querySelectorAll ret ...

A guide on setting up an HTTP proxy for API requests in Next.js

After exhausting my options online, I still haven't found a solution that works. My First Attempt (src/pages/api/proxy/[...slug].js): import { createProxyMiddleware } from 'http-proxy-middleware'; // Defining the proxy instance outside of t ...

Updating non-data properties dynamically in a custom AG Grid cell renderer

In my grid setup, I have implemented an editor button in a column for each row and a new item creator button outside the grid. One of the requirements is that all buttons should be disabled when either the create or edit button is clicked. To achieve thi ...