Apollo Client is refusing in any circumstances to update cached data with the ones from the server. We are running Apollo Client in Next.js (14.2.5) SSR using the getClient()
method below:
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> = {};
// Populate merged array and map from existing features
existing.forEach((feature: any, index: any) => {
const name = readField<string>("name", feature);
if (name) {
featureNameToIndex[name] = index;
}
});
// Merge or add incoming features
incoming.forEach((feature) => {
const name = readField<string>("name", feature);
if (name) {
const index = featureNameToIndex[name];
if (typeof index === "number") {
// Merge existing and incoming feature data
merged[index] = {
...merged[index],
...feature,
};
} else {
// Add new feature
featureNameToIndex[name] = merged.length;
merged.push(feature);
}
}
});
return merged;
},
},
},
},
},
}),
/*defaultOptions: {
watchQuery: {
fetchPolicy: "no-cache",
errorPolicy: "ignore",
},
query: {
fetchPolicy: "no-cache",
errorPolicy: "all",
},
mutate: {
fetchPolicy: "no-cache",
},
},*/
});
});
However making a query, as for example the one below, to our API (which is updating its data correctly, verified through Postman) will return data which are not up to date:
"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;
};
We have also tried inserting individual fetch-policy
to each query
set to no-cache
, but nothing changes.
We need to get rid of any caching, since our app needs to make a query on each time the website is loaded with data from the API. We have also tried switching to different clients or disabling caching in Next.js, but nothing's helping.
Here's how we are making the server-side query in the 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;
This is not Apollo Client caching your requests, but Next.js caching outgoing fetch calls.
See the Next.js documentation on fetch caching
You need to set fetchOptions: { cache: "no-store" }
to tell Next.js to stop that. This example from the README of the @apollo/experimental-nextjs-app-support
package shows that:
export const { getClient, query, PreloadQuery } = registerApolloClient(() => {
return new ApolloClient({
cache: new InMemoryCache(),
link: new HttpLink({
// this needs to be an absolute url, as relative urls cannot be used in SSR
uri: "http://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" },
}),
});
});
Please remove those
ssrMode: true,
ssrForceFetchDelay: 1,
they don't do anything with streaming SSR.
You also don't need resultCaching: false,
and probably most of the other options.