A fully-featured caching GraphQL client.
Last release 6 days ago
21 Aug 2026
Ships on a steady schedule
a new release about every 2 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
27 versions withdrawn
withdrawn after publishing
7 years old
723 releases · first in 2019
Release timeline
723 releases since 2019Releases
- 3.9.47 Feb 2024
Release notes3 sources agree
Open source →Patch Changes
-
#11403
b0c4f3aThanks @jerelmiller! - Fix issue inuseLazyQuerythat results in a double network call when calling the execute function with no arguments after having called it previously with another set of arguments. -
#11576
e855d00Thanks @alessbell! - Revert PR #11202 to fix caching bug reported in #11560
-
- 3.9.36 Feb 2024
Release notes3 sources agree
Open source →Patch Changes
-
#11525
dce923aThanks @vezaynk! - Allows passing in client via options to useFragment -
#11558
8cba16fThanks @alessbell! - Fixunbound-methodlinter error on ObservableQuery methods exposed on useQuery's QueryResult object.
-
- 3.9.21 Feb 2024
Release notes3 sources agree
Open source →Patch Changes
- #11552
6ac2b0cThanks @jerelmiller! - Fix import inuseLazyRefcausing import issues in the nextjs package.
- #11552
- 3.9.131 Jan 2024
Release notes3 sources agree
Open source →Patch Changes
-
#11516
8390feaThanks @phryneas! - Fix an incorrect string substitution in a warning message. -
#11515
c9bf93bThanks @vladar! - Avoid redundant refetchQueries call for mutation with no-cache policy (fixes #10238) -
#11545
84a6beaThanks @alessbell! - Remove error thrown byinFlightLinkObservablesintended to be removed before 3.9 release.
-
- 3.9.030 Jan 2024
Release notes
Open source →Minor Changes
Memory optimizations
-
#11424
62f3b6dThanks @phryneas! - Simplify RetryLink, fix potential memory leakHistorically,
RetryLinkwould keep avaluesarray of all previous values, in case the operation would get an additional subscriber at a later point in time.In practice, this could lead to a memory leak (#11393) and did not serve any further purpose, as the resulting observable would only be subscribed to by Apollo Client itself, and only once - it would be wrapped in a
Concastbefore being exposed to the user, and thatConcastwould handle subscribers on its own. -
#11435
5cce53eThanks @phryneas! - DeprecatescanonizeResults.Using
canonizeResultscan result in memory leaks so we generally do not recommend using this option anymore. A future version of Apollo Client will contain a similar feature without the risk of memory leaks. -
#11254
d08970dThanks @benjamn! - DecouplecanonicalStringifyfromObjectCanonfor better time and memory performance. -
#11356
cc4ac7eThanks @phryneas! - Fix a potential memory leak inFragmentRegistry.transformandFragmentRegistry.findFragmentSpreadsthat would hold on to passed-inDocumentNodesfor too long. -
#11370
25e2cb4Thanks @phryneas! -parsefunction: improve memory management- use LRU
WeakCacheinstead ofMapto keep a limited number of parsed results - cache is initiated lazily, only when needed
- expose
parse.resetCache()method
- use LRU
-
#11389
139acd1Thanks @phryneas! -documentTransform: useoptimismandWeakCacheinstead of directly storing data on theTrie -
#11358
7d939f8Thanks @phryneas! - Fixes a potential memory leak inConcastthat might have been triggered whenConcastwas used outside of Apollo Client. -
#11344
bd26676Thanks @phryneas! - Add aresetCachemethod toDocumentTransformand hookInMemoryCache.addTypenameTransformup toInMemoryCache.gc -
#11367
30d17bfThanks @phryneas! -print: useWeakCacheinstead ofWeakMap -
#11387
4dce867Thanks @phryneas! -QueryManager.transformCache: useWeakCacheinstead ofWeakMap -
#11369
2a47164Thanks @phryneas! - Persisted Query Link: improve memory management- use LRU
WeakCacheinstead ofWeakMapto keep a limited number of hash results - hash cache is initiated lazily, only when needed
- expose
persistedLink.resetHashCache()method - reset hash cache if the upstream server reports it doesn't accept persisted queries
- use LRU
-
#10804
221dd99Thanks @phryneas! - use WeakMap in React Native with Hermes -
#11355
7d8e184Thanks @phryneas! - InMemoryCache.gc now also triggers FragmentRegistry.resetCaches (if there is a FragmentRegistry) -
#11409
2e7203bThanks @phryneas! - Adds an experimentalApolloClient.getMemoryInternalshelper -
#11343
776631dThanks @phryneas! - Addresetmethod toprint, hook up toInMemoryCache.gc
Suspense-enabled data fetching on user interaction with
useLoadableQuery-
#11300
a815873Thanks @jerelmiller! - Introduces a newuseLoadableQueryhook. This hook works similarly touseBackgroundQueryin that it returns aqueryRefthat can be used to suspend a component via theuseReadQueryhook. It provides a more ergonomic way to load the query during a user interaction (for example when wanting to preload some data) that would otherwise be clunky withuseBackgroundQuery.function App() { const [loadQuery, queryRef, { refetch, fetchMore, reset }] = useLoadableQuery(query, options); return ( <> <button onClick={() => loadQuery(variables)}>Load query</button> <Suspense fallback={<SuspenseFallback />}> {queryRef && <Child queryRef={queryRef} />} </Suspense> </> ); } function Child({ queryRef }) { const { data } = useReadQuery(queryRef); // ... }
Begin preloading outside of React with
createQueryPreloader- #11412
58db5c3Thanks @jerelmiller! - Add the ability to start preloading a query outside React to begin fetching as early as possible. CallcreateQueryPreloaderto create apreloadQueryfunction which can be called to start fetching a query. This returns aqueryRefwhich is passed touseReadQueryand suspended until the query is done fetching.
Testing utility improvements
-
#11178
4d64a6fThanks @sebakerckhof! - Support re-using of mocks in the MockedProvider -
#6701
8d2b4e1Thanks @prowe! - Ability to dynamically match mocksAdds support for a new property
MockedResponse.variableMatcher: a predicate function that accepts avariablesparam. Iftrue, thevariableswill be passed into theResultFunctionto help dynamically build a response.
New
useQueryRefHandlershook-
#11412
58db5c3Thanks @jerelmiller! - Create a newuseQueryRefHandlershook that returnsrefetchandfetchMorefunctions for a givenqueryRef. This is useful to get access to handlers for aqueryRefthat was created bycreateQueryPreloaderor when the handlers for aqueryRefproduced by a different component are inaccessible.const MyComponent({ queryRef }) { const { refetch, fetchMore } = useQueryRefHandlers(queryRef); // ... }
Bail out of
optimisticResponseupdates with theIGNOREsentinel object-
#11410
07fcf6aThanks @sf-twingate! - Allow returningIGNOREsentinel object fromoptimisticResponsefunctions to bail-out from the optimistic update.Consider this example:
const UPDATE_COMMENT = gql` mutation UpdateComment($commentId: ID!, $commentContent: String!) { updateComment(commentId: $commentId, content: $commentContent) { id __typename content } } `; function CommentPageWithData() { const [mutate] = useMutation(UPDATE_COMMENT); return ( <Comment updateComment={({ commentId, commentContent }) => mutate({ variables: { commentId, commentContent }, optimisticResponse: (vars, { IGNORE }) => { if (commentContent === "foo") { // conditionally bail out of optimistic updates return IGNORE; } return { updateComment: { id: commentId, __typename: "Comment", content: commentContent, }, }; }, }) } /> ); }The
IGNOREsentinel can be destructured from the second parameter in the callback function signature passed tooptimisticResponse.const preloadQuery = createQueryPreloader(client); const queryRef = preloadQuery(QUERY, { variables, ...otherOptions }); function App() { return { <Suspense fallback={<div>Loading</div>}> <MyQuery /> </Suspense> } } function MyQuery() { const { data } = useReadQuery(queryRef); // do something with data }
Network adapters for multipart subscriptions usage with Relay and urql
-
#11301
46ab032Thanks @alessbell! - Add multipart subscription network adapters for Relay and urqlRelay
import { createFetchMultipartSubscription } from "@apollo/client/utilities/subscriptions/relay"; import { Environment, Network, RecordSource, Store } from "relay-runtime"; const fetchMultipartSubs = createFetchMultipartSubscription( "http://localhost:4000", ); const network = Network.create(fetchQuery, fetchMultipartSubs); export const RelayEnvironment = new Environment({ network, store: new Store(new RecordSource()), });Urql
import { createFetchMultipartSubscription } from "@apollo/client/utilities/subscriptions/urql"; import { Client, fetchExchange, subscriptionExchange } from "@urql/core"; const url = "http://localhost:4000"; const multipartSubscriptionForwarder = createFetchMultipartSubscription(url); const client = new Client({ url, exchanges: [ fetchExchange, subscriptionExchange({ forwardSubscription: multipartSubscriptionForwarder, }), ], });
skipPollAttemptcallback function-
#11397
3f7eecbThanks @aditya-kumawat! - Adds a newskipPollAttemptcallback function that's called whenever a refetch attempt occurs while polling. If the function returnstrue, the refetch is skipped and not reattempted until the next poll interval. This will solve the frequent use-case of disabling polling when the window is inactive.useQuery(QUERY, { pollInterval: 1000, skipPollAttempt: () => document.hidden, // or !document.hasFocus() }); // or define it globally new ApolloClient({ defaultOptions: { watchQuery: { skipPollAttempt: () => document.hidden, // or !document.hasFocus() }, }, });
QueryManager.inFlightLinkObservablesnow uses a strongTrieas an internal data structure-
#11345
1759066Thanks @phryneas!Warning: requires
@apollo/experimental-nextjs-app-supportupdateIf you are using
@apollo/experimental-nextjs-app-support, you will need to update that to at least 0.5.2, as it accesses this internal data structure.
<details open> <summary><h4>More Minor Changes</h4></summary>
-
#11202
7c2bc08Thanks @benjamn! - PreventQueryInfo#markResultmutation ofresult.dataand return cache data consistently whether complete or incomplete. -
#11442
4b6f2bcThanks @jerelmiller! - Remove the need to callretainfromuseLoadableQuerysinceuseReadQuerywill now retain the query. This means that aqueryRefthat is not consumed byuseReadQuerywithin the givenautoDisposeTimeoutMswill now be auto diposed for you.Thanks to #11412, disposed query refs will be automatically resubscribed to the query when consumed by
useReadQueryafter it has been disposed. -
#11438
6d46ab9Thanks @jerelmiller! - Remove the need to callretainfromuseBackgroundQuerysinceuseReadQuerywill now retain the query. This means that aqueryRefthat is not consumed byuseReadQuerywithin the givenautoDisposeTimeoutMswill now be auto diposed for you.Thanks to #11412, disposed query refs will be automatically resubscribed to the query when consumed by
useReadQueryafter it has been disposed. -
#11175
d6d1491Thanks @phryneas! - To work around issues in React Server Components, especially with bundling for the Next.js "edge" runtime we now use an external package to wrapreactimports instead of importing React directly. -
#11495
1190aa5Thanks @jerelmiller! - Increase the default memory limits forexecuteSelectionSetandexecuteSelectionSetArray.
</details>
<details open> <summary><h3>Patch Changes</h3></summary>
-
#11275
3862f9bThanks @phryneas! - Add adefaultContextoption and property onApolloClient, e.g. for keeping track of changing auth tokens or dependency injection.This can be used e.g. in authentication scenarios, where a new token might be generated outside of the link chain and should passed into the link chain.
import { ApolloClient, createHttpLink, InMemoryCache } from "@apollo/client"; import { setContext } from "@apollo/client/link/context"; const httpLink = createHttpLink({ uri: "/graphql", }); const authLink = setContext((_, { headers, token }) => { return { headers: { ...headers, authorization: token ? `Bearer ${token}` : "", }, }; }); const client = new ApolloClient({ link: authLink.concat(httpLink), cache: new InMemoryCache(), }); // somewhere else in your application function onNewToken(newToken) { // token can now be changed for future requests without need for a global // variable, scoped ref or recreating the client client.defaultContext.token = newToken; } -
#11443
ff5a332Thanks @phryneas! - Adds a deprecation warning to the HOC and render prop APIs.The HOC and render prop APIs have already been deprecated since 2020, but we previously didn't have a
@deprecatedtag in the DocBlocks. -
#11385
d9ca4f0Thanks @phryneas! - ensuredefaultContextis also used for mutations and subscriptions -
#11503
67f62e3Thanks @jerelmiller! - Release changes fromv3.8.10 -
#11078
14edebeThanks @phryneas! - ObservableQuery: prevent reporting results of previous queries if the variables changed since -
#11439
33454f0Thanks @jerelmiller! - Address bundling issue introduced in #11412 where thereact/cacheinternals ended up duplicated in the bundle. This was due to the fact that we had areact/hooksentrypoint that imported these files along with the newly introducedcreateQueryPreloaderfunction, which lived outside of thereact/hooksfolder. -
#11371
ebd8fe2Thanks @phryneas! - Clarify types ofEntityStore.makeCacheKey.
</details>
Additional notes2 sources agree
Open source →Minor Changes
Memory optimizations
-
#11424
62f3b6dThanks @phryneas! - Simplify RetryLink, fix potential memory leakHistorically,
RetryLinkwould keep avaluesarray of all previous values, in case the operation would get an additional subscriber at a later point in time.In practice, this could lead to a memory leak (#11393) and did not serve any further purpose, as the resulting observable would only be subscribed to by Apollo Client itself, and only once - it would be wrapped in a
Concastbefore being exposed to the user, and thatConcastwould handle subscribers on its own. -
#11435
5cce53eThanks @phryneas! - DeprecatescanonizeResults.Using
canonizeResultscan result in memory leaks so we generally do not recommend using this option anymore. A future version of Apollo Client will contain a similar feature without the risk of memory leaks. -
#11254
d08970dThanks @benjamn! - DecouplecanonicalStringifyfromObjectCanonfor better time and memory performance. -
#11356
cc4ac7eThanks @phryneas! - Fix a potential memory leak inFragmentRegistry.transformandFragmentRegistry.findFragmentSpreadsthat would hold on to passed-inDocumentNodesfor too long. -
#11370
25e2cb4Thanks @phryneas! -parsefunction: improve memory management- use LRU
WeakCacheinstead ofMapto keep a limited number of parsed results - cache is initiated lazily, only when needed
- expose
parse.resetCache()method
- use LRU
-
#11389
139acd1Thanks @phryneas! -documentTransform: useoptimismandWeakCacheinstead of directly storing data on theTrie -
#11358
7d939f8Thanks @phryneas! - Fixes a potential memory leak inConcastthat might have been triggered whenConcastwas used outside of Apollo Client. -
#11344
bd26676Thanks @phryneas! - Add aresetCachemethod toDocumentTransformand hookInMemoryCache.addTypenameTransformup toInMemoryCache.gc -
#11367
30d17bfThanks @phryneas! -print: useWeakCacheinstead ofWeakMap -
#11387
4dce867Thanks @phryneas! -QueryManager.transformCache: useWeakCacheinstead ofWeakMap -
#11369
2a47164Thanks @phryneas! - Persisted Query Link: improve memory management- use LRU
WeakCacheinstead ofWeakMapto keep a limited number of hash results - hash cache is initiated lazily, only when needed
- expose
persistedLink.resetHashCache()method - reset hash cache if the upstream server reports it doesn't accept persisted queries
- use LRU
-
#10804
221dd99Thanks @phryneas! - use WeakMap in React Native with Hermes -
#11355
7d8e184Thanks @phryneas! - InMemoryCache.gc now also triggers FragmentRegistry.resetCaches (if there is a FragmentRegistry) -
#11409
2e7203bThanks @phryneas! - Adds an experimentalApolloClient.getMemoryInternalshelper -
#11343
776631dThanks @phryneas! - Addresetmethod toprint, hook up toInMemoryCache.gc
Suspense-enabled data fetching on user interaction with
useLoadableQuery-
#11300
a815873Thanks @jerelmiller! - Introduces a newuseLoadableQueryhook. This hook works similarly touseBackgroundQueryin that it returns aqueryRefthat can be used to suspend a component via theuseReadQueryhook. It provides a more ergonomic way to load the query during a user interaction (for example when wanting to preload some data) that would otherwise be clunky withuseBackgroundQuery.function App() { const [loadQuery, queryRef, { refetch, fetchMore, reset }] = useLoadableQuery(query, options); return ( <> <button onClick={() => loadQuery(variables)}>Load query</button> <Suspense fallback={<SuspenseFallback />}> {queryRef && <Child queryRef={queryRef} />} </Suspense> </> ); } function Child({ queryRef }) { const { data } = useReadQuery(queryRef); // ... }
Begin preloading outside of React with
createQueryPreloader-
#11412
58db5c3Thanks @jerelmiller! - Add the ability to start preloading a query outside React to begin fetching as early as possible. CallcreateQueryPreloaderto create apreloadQueryfunction which can be called to start fetching a query. This returns aqueryRefwhich is passed touseReadQueryand suspended until the query is done fetching.const preloadQuery = createQueryPreloader(client); const queryRef = preloadQuery(QUERY, { variables, ...otherOptions }); function App() { return { <Suspense fallback={<div>Loading</div>}> <MyQuery /> </Suspense> } } function MyQuery() { const { data } = useReadQuery(queryRef); // do something with data }
Testing utility improvements
-
#11178
4d64a6fThanks @sebakerckhof! - Support re-using of mocks in the MockedProvider -
#6701
8d2b4e1Thanks @prowe! - Ability to dynamically match mocksAdds support for a new property
MockedResponse.variableMatcher: a predicate function that accepts avariablesparam. Iftrue, thevariableswill be passed into theResultFunctionto help dynamically build a response.
New
useQueryRefHandlershook-
#11412
58db5c3Thanks @jerelmiller! - Create a newuseQueryRefHandlershook that returnsrefetchandfetchMorefunctions for a givenqueryRef. This is useful to get access to handlers for aqueryRefthat was created bycreateQueryPreloaderor when the handlers for aqueryRefproduced by a different component are inaccessible.const MyComponent({ queryRef }) { const { refetch, fetchMore } = useQueryRefHandlers(queryRef); // ... }
Bail out of
optimisticResponseupdates with theIGNOREsentinel object-
#11410
07fcf6aThanks @sf-twingate! - Allow returningIGNOREsentinel object fromoptimisticResponsefunctions to bail-out from the optimistic update.Consider this example:
const UPDATE_COMMENT = gql` mutation UpdateComment($commentId: ID!, $commentContent: String!) { updateComment(commentId: $commentId, content: $commentContent) { id __typename content } } `; function CommentPageWithData() { const [mutate] = useMutation(UPDATE_COMMENT); return ( <Comment updateComment={({ commentId, commentContent }) => mutate({ variables: { commentId, commentContent }, optimisticResponse: (vars, { IGNORE }) => { if (commentContent === "foo") { // conditionally bail out of optimistic updates return IGNORE; } return { updateComment: { id: commentId, __typename: "Comment", content: commentContent, }, }; }, }) } /> ); }The
IGNOREsentinel can be destructured from the second parameter in the callback function signature passed tooptimisticResponse.
Network adapters for multipart subscriptions usage with Relay and urql
-
#11301
46ab032Thanks @alessbell! - Add multipart subscription network adapters for Relay and urqlRelay
import { createFetchMultipartSubscription } from "@apollo/client/utilities/subscriptions/relay"; import { Environment, Network, RecordSource, Store } from "relay-runtime"; const fetchMultipartSubs = createFetchMultipartSubscription( "http://localhost:4000" ); const network = Network.create(fetchQuery, fetchMultipartSubs); export const RelayEnvironment = new Environment({ network, store: new Store(new RecordSource()), });Urql
import { createFetchMultipartSubscription } from "@apollo/client/utilities/subscriptions/urql"; import { Client, fetchExchange, subscriptionExchange } from "@urql/core"; const url = "http://localhost:4000"; const multipartSubscriptionForwarder = createFetchMultipartSubscription(url); const client = new Client({ url, exchanges: [ fetchExchange, subscriptionExchange({ forwardSubscription: multipartSubscriptionForwarder, }), ], });
skipPollAttemptcallback function-
#11397
3f7eecbThanks @aditya-kumawat! - Adds a newskipPollAttemptcallback function that's called whenever a refetch attempt occurs while polling. If the function returnstrue, the refetch is skipped and not reattempted until the next poll interval. This will solve the frequent use-case of disabling polling when the window is inactive.useQuery(QUERY, { pollInterval: 1000, skipPollAttempt: () => document.hidden, // or !document.hasFocus() }); // or define it globally new ApolloClient({ defaultOptions: { watchQuery: { skipPollAttempt: () => document.hidden, // or !document.hasFocus() }, }, });
QueryManager.inFlightLinkObservablesnow uses a strongTrieas an internal data structure-
#11345
1759066Thanks @phryneas!Warning: requires
@apollo/experimental-nextjs-app-supportupdateIf you are using
@apollo/experimental-nextjs-app-support, you will need to update that to at least 0.5.2, as it accesses this internal data structure.
<details open> <summary><h4>More Minor Changes</h4></summary>
-
#11202
7c2bc08Thanks @benjamn! - PreventQueryInfo#markResultmutation ofresult.dataand return cache data consistently whether complete or incomplete. -
#11442
4b6f2bcThanks @jerelmiller! - Remove the need to callretainfromuseLoadableQuerysinceuseReadQuerywill now retain the query. This means that aqueryRefthat is not consumed byuseReadQuerywithin the givenautoDisposeTimeoutMswill now be auto diposed for you.Thanks to #11412, disposed query refs will be automatically resubscribed to the query when consumed by
useReadQueryafter it has been disposed. -
#11438
6d46ab9Thanks @jerelmiller! - Remove the need to callretainfromuseBackgroundQuerysinceuseReadQuerywill now retain the query. This means that aqueryRefthat is not consumed byuseReadQuerywithin the givenautoDisposeTimeoutMswill now be auto diposed for you.Thanks to #11412, disposed query refs will be automatically resubscribed to the query when consumed by
useReadQueryafter it has been disposed. -
#11175
d6d1491Thanks @phryneas! - To work around issues in React Server Components, especially with bundling for the Next.js "edge" runtime we now use an external package to wrapreactimports instead of importing React directly. -
#11495
1190aa5Thanks @jerelmiller! - Increase the default memory limits forexecuteSelectionSetandexecuteSelectionSetArray.
</details>
<details open> <summary><h3>Patch Changes</h3></summary>
-
#11275
3862f9bThanks @phryneas! - Add adefaultContextoption and property onApolloClient, e.g. for keeping track of changing auth tokens or dependency injection.This can be used e.g. in authentication scenarios, where a new token might be generated outside of the link chain and should passed into the link chain.
import { ApolloClient, createHttpLink, InMemoryCache } from "@apollo/client"; import { setContext } from "@apollo/client/link/context"; const httpLink = createHttpLink({ uri: "/graphql", }); const authLink = setContext((_, { headers, token }) => { return { headers: { ...headers, authorization: token ? `Bearer ${token}` : "", }, }; }); const client = new ApolloClient({ link: authLink.concat(httpLink), cache: new InMemoryCache(), }); // somewhere else in your application function onNewToken(newToken) { // token can now be changed for future requests without need for a global // variable, scoped ref or recreating the client client.defaultContext.token = newToken; } -
#11443
ff5a332Thanks @phryneas! - Adds a deprecation warning to the HOC and render prop APIs.The HOC and render prop APIs have already been deprecated since 2020, but we previously didn't have a
@deprecatedtag in the DocBlocks. -
#11385
d9ca4f0Thanks @phryneas! - ensuredefaultContextis also used for mutations and subscriptions -
#11503
67f62e3Thanks @jerelmiller! - Release changes fromv3.8.10 -
#11078
14edebeThanks @phryneas! - ObservableQuery: prevent reporting results of previous queries if the variables changed since -
#11439
33454f0Thanks @jerelmiller! - Address bundling issue introduced in #11412 where thereact/cacheinternals ended up duplicated in the bundle. This was due to the fact that we had areact/hooksentrypoint that imported these files along with the newly introducedcreateQueryPreloaderfunction, which lived outside of thereact/hooksfolder. -
#11371
ebd8fe2Thanks @phryneas! - Clarify types ofEntityStore.makeCacheKey.
</details>
-
- 3.9.0-rc.118 Jan 2024pre-release
Release notes
Open source →Patch Changes
- #11503
67f62e3Thanks @jerelmiller! - Release changes fromv3.8.10
- #11503
- 3.9.0-rc.017 Jan 2024pre-release
Release notes
Open source →Minor Changes
- #11495
1190aa5Thanks @jerelmiller! - Increase the default memory limits forexecuteSelectionSetandexecuteSelectionSetArray.
- #11495
- 3.9.0-beta.121 Dec 2023pre-release
Release notes
Open source →Minor Changes
-
#11424
62f3b6dThanks @phryneas! - Simplify RetryLink, fix potential memory leakHistorically,
RetryLinkwould keep avaluesarray of all previous values, in case the operation would get an additional subscriber at a later point in time. In practice, this could lead to a memory leak (#11393) and did not serve any further purpose, as the resulting observable would only be subscribed to by Apollo Client itself, and only once - it would be wrapped in aConcastbefore being exposed to the user, and thatConcastwould handle subscribers on its own. -
#11442
4b6f2bcThanks @jerelmiller! - Remove the need to callretainfromuseLoadableQuerysinceuseReadQuerywill now retain the query. This means that aqueryRefthat is not consumed byuseReadQuerywithin the givenautoDisposeTimeoutMswill now be auto diposed for you.Thanks to #11412, disposed query refs will be automatically resubscribed to the query when consumed by
useReadQueryafter it has been disposed. -
#11438
6d46ab9Thanks @jerelmiller! - Remove the need to callretainfromuseBackgroundQuerysinceuseReadQuerywill now retain the query. This means that aqueryRefthat is not consumed byuseReadQuerywithin the givenautoDisposeTimeoutMswill now be auto diposed for you.Thanks to #11412, disposed query refs will be automatically resubscribed to the query when consumed by
useReadQueryafter it has been disposed.
Patch Changes
-
#11443
ff5a332Thanks @phryneas! - Adds a deprecation warning to the HOC and render prop APIs.The HOC and render prop APIs have already been deprecated since 2020, but we previously didn't have a @deprecated tag in the DocBlocks.
-
#11078
14edebeThanks @phryneas! - ObservableQuery: prevent reporting results of previous queries if the variables changed since -
#11439
33454f0Thanks @jerelmiller! - Address bundling issue introduced in #11412 where thereact/cacheinternals ended up duplicated in the bundle. This was due to the fact that we had areact/hooksentrypoint that imported these files along with the newly introducedcreateQueryPreloaderfunction, which lived outside of thereact/hooksfolder.
-
- 3.9.0-beta.018 Dec 2023pre-release
Release notes
Open source →Minor Changes
-
#11412
58db5c3Thanks @jerelmiller! - Create a newuseQueryRefHandlershook that returnsrefetchandfetchMorefunctions for a givenqueryRef. This is useful to get access to handlers for aqueryRefthat was created bycreateQueryPreloaderor when the handlers for aqueryRefproduced by a different component are inaccessible.const MyComponent({ queryRef }) { const { refetch, fetchMore } = useQueryRefHandlers(queryRef); // ... } -
#11410
07fcf6aThanks @sf-twingate! - Allow returningIGNOREsentinel object fromoptimisticResponsefunctions to bail-out from the optimistic update.Consider this example:
const UPDATE_COMMENT = gql` mutation UpdateComment($commentId: ID!, $commentContent: String!) { updateComment(commentId: $commentId, content: $commentContent) { id __typename content } } `; function CommentPageWithData() { const [mutate] = useMutation(UPDATE_COMMENT); return ( <Comment updateComment={({ commentId, commentContent }) => mutate({ variables: { commentId, commentContent }, optimisticResponse: (vars, { IGNORE }) => { if (commentContent === "foo") { // conditionally bail out of optimistic updates return IGNORE; } return { updateComment: { id: commentId, __typename: "Comment", content: commentContent, }, }; }, }) } /> ); }The
IGNOREsentinel can be destructured from the second parameter in the callback function signature passed tooptimisticResponse. -
#11412
58db5c3Thanks @jerelmiller! - Add the ability to start preloading a query outside React to begin fetching as early as possible. CallcreateQueryPreloaderto create apreloadQueryfunction which can be called to start fetching a query. This returns aqueryRefwhich is passed touseReadQueryand suspended until the query is done fetching.const preloadQuery = createQueryPreloader(client); const queryRef = preloadQuery(QUERY, { variables, ...otherOptions }); function App() { return { <Suspense fallback={<div>Loading</div>}> <MyQuery /> </Suspense> } } function MyQuery() { const { data } = useReadQuery(queryRef); // do something with data } -
#11397
3f7eecbThanks @aditya-kumawat! - Adds a newskipPollAttemptcallback function that's called whenever a refetch attempt occurs while polling. If the function returnstrue, the refetch is skipped and not reattempted until the next poll interval. This will solve the frequent use-case of disabling polling when the window is inactive.useQuery(QUERY, { pollInterval: 1000, skipPollAttempt: () => document.hidden, // or !document.hasFocus() }); // or define it globally new ApolloClient({ defaultOptions: { watchQuery: { skipPollAttempt: () => document.hidden, // or !document.hasFocus() }, }, }); -
#11435
5cce53eThanks @phryneas! - DeprecatescanonizeResults.Using
canonizeResultscan result in memory leaks so we generally do not recommend using this option anymore. A future version of Apollo Client will contain a similar feature without the risk of memory leaks.
Patch Changes
-
#11369
2a47164Thanks @phryneas! - Persisted Query Link: improve memory management- use LRU
WeakCacheinstead ofWeakMapto keep a limited number of hash results - hash cache is initiated lazily, only when needed
- expose
persistedLink.resetHashCache()method - reset hash cache if the upstream server reports it doesn't accept persisted queries
- use LRU
-
#10804
221dd99Thanks @phryneas! - use WeakMap in React Native with Hermes -
#11409
2e7203bThanks @phryneas! - Adds an experimentalApolloClient.getMemoryInternalshelper
-
- 3.9.0-alpha.55 Dec 2023pre-release
Release notes
Open source →Minor Changes
-
#11345
1759066a8Thanks @phryneas! -QueryManager.inFlightLinkObservablesnow uses a strongTrieas an internal data structure.Warning: requires
@apollo/experimental-nextjs-app-supportupdateIf you are using
@apollo/experimental-nextjs-app-support, you will need to update that to at least 0.5.2, as it accesses this internal data structure. -
#11300
a8158733cThanks @jerelmiller! - Introduces a newuseLoadableQueryhook. This hook works similarly touseBackgroundQueryin that it returns aqueryRefthat can be used to suspend a component via theuseReadQueryhook. It provides a more ergonomic way to load the query during a user interaction (for example when wanting to preload some data) that would otherwise be clunky withuseBackgroundQuery.function App() { const [loadQuery, queryRef, { refetch, fetchMore, reset }] = useLoadableQuery(query, options); return ( <> <button onClick={() => loadQuery(variables)}>Load query</button> <Suspense fallback={<SuspenseFallback />}> {queryRef && <Child queryRef={queryRef} />} </Suspense> </> ); } function Child({ queryRef }) { const { data } = useReadQuery(queryRef); // ... }
Patch Changes
-
#11356
cc4ac7e19Thanks @phryneas! - Fix a potential memory leak inFragmentRegistry.transformandFragmentRegistry.findFragmentSpreadsthat would hold on to passed-inDocumentNodesfor too long. -
#11370
25e2cb431Thanks @phryneas! -parsefunction: improve memory management- use LRU
WeakCacheinstead ofMapto keep a limited number of parsed results - cache is initiated lazily, only when needed
- expose
parse.resetCache()method
- use LRU
-
#11389
139acd115Thanks @phryneas! -documentTransform: useoptimismandWeakCacheinstead of directly storing data on theTrie -
#11358
7d939f80fThanks @phryneas! - Fixes a potential memory leak inConcastthat might have been triggered whenConcastwas used outside of Apollo Client. -
#11344
bd2667619Thanks @phryneas! - Add aresetCachemethod toDocumentTransformand hookInMemoryCache.addTypenameTransformup toInMemoryCache.gc -
#11367
30d17bfebThanks @phryneas! -print: useWeakCacheinstead ofWeakMap -
#11385
d9ca4f082Thanks @phryneas! - ensuredefaultContextis also used for mutations and subscriptions -
#11387
4dce8673bThanks @phryneas! -QueryManager.transformCache: useWeakCacheinstead ofWeakMap -
#11371
ebd8fe2c1Thanks @phryneas! - Clarify types ofEntityStore.makeCacheKey. -
#11355
7d8e18493Thanks @phryneas! - InMemoryCache.gc now also triggers FragmentRegistry.resetCaches (if there is a FragmentRegistry)
-
- 3.9.0-alpha.48 Nov 2023pre-release
Release notes
Open source →Minor Changes
- #11175
d6d14911cThanks @phryneas! - To work around issues in React Server Components, especially with bundling for the Next.js "edge" runtime we now use an external package to wrapreactimports instead of importing React directly.
Patch Changes
- #11175
- 3.9.0-alpha.32 Nov 2023pre-release
Release notes
Open source →Minor Changes
-
#11301
46ab032afThanks @alessbell! - Add multipart subscription network adapters for Relay and urqlRelay
import { createFetchMultipartSubscription } from "@apollo/client/utilities/subscriptions/relay"; import { Environment, Network, RecordSource, Store } from "relay-runtime"; const fetchMultipartSubs = createFetchMultipartSubscription( "http://localhost:4000" ); const network = Network.create(fetchQuery, fetchMultipartSubs); export const RelayEnvironment = new Environment({ network, store: new Store(new RecordSource()), });Urql
import { createFetchMultipartSubscription } from "@apollo/client/utilities/subscriptions/urql"; import { Client, fetchExchange, subscriptionExchange } from "@urql/core"; const url = "http://localhost:4000"; const multipartSubscriptionForwarder = createFetchMultipartSubscription(url); const client = new Client({ url, exchanges: [ fetchExchange, subscriptionExchange({ forwardSubscription: multipartSubscriptionForwarder, }), ], });
Patch Changes
-
#11275
3862f9ba9Thanks @phryneas! - Add adefaultContextoption and property onApolloClient, e.g. for keeping track of changing auth tokens or dependency injection.This can be used e.g. in authentication scenarios, where a new token might be generated outside of the link chain and should passed into the link chain.
import { ApolloClient, createHttpLink, InMemoryCache } from "@apollo/client"; import { setContext } from "@apollo/client/link/context"; const httpLink = createHttpLink({ uri: "/graphql", }); const authLink = setContext((_, { headers, token }) => { return { headers: { ...headers, authorization: token ? `Bearer ${token}` : "", }, }; }); const client = new ApolloClient({ link: authLink.concat(httpLink), cache: new InMemoryCache(), }); // somewhere else in your application function onNewToken(newToken) { // token can now be changed for future requests without need for a global // variable, scoped ref or recreating the client client.defaultContext.token = newToken; } -
#11297
c8c76a522Thanks @jerelmiller! - Add an explicit return type for theuseReadQueryhook calledUseReadQueryResult. Previously the return type of this hook was inferred from the return value.
-
- 3.9.0-alpha.211 Oct 2023pre-release
- 3.9.0-alpha.121 Sept 2023pre-release
Release notes
Open source →Minor Changes
- #11178
4d64a6fa2Thanks @sebakerckhof! - Support re-using of mocks in the MockedProvider
- #11178
- 3.9.0-alpha.019 Sept 2023pre-release
Release notes
Open source →Minor Changes
-
#11202
7c2bc08b2Thanks @benjamn! - PreventQueryInfo#markResultmutation ofresult.dataand return cache data consistently whether complete or incomplete. -
#6701
8d2b4e107Thanks @prowe! - Ability to dynamically match mocksAdds support for a new property
MockedResponse.variableMatcher: a predicate function that accepts avariablesparam. Iftrue, thevariableswill be passed into theResultFunctionto help dynamically build a response.
-
- 3.8.1018 Jan 2024
- 3.8.99 Jan 2024
Release notes3 sources agree
Open source →Patch Changes
-
#11472
afc844dThanks @alessbell! - Fix delay: Infinity when set on a MockResponse passed to Mocked Provider so it indefinitely enters loading state. -
#11464
aac12b2Thanks @jerelmiller! - PreventuseFragmentfrom excessively unsubscribing and resubscribing the fragment with the cache on every render. -
#11449
f40cda4Thanks @phryneas! - Removes refences to the typescript "dom" lib. -
#11470
e293bc9Thanks @phryneas! - Remove an unnecessary check from parseAndCheckHttpResponse.
-
- 3.8.829 Nov 2023
Release notes3 sources agree
Open source →Patch Changes
-
#11200
ae5091a21Thanks @jerelmiller! - Enablestrictin tsconfig for the entire project. -
#11332
291aea56bThanks @asvishnyakov! - Add missed reexports of MutationFetchPolicy and RefetchWritePolicy to @apollo/client/core -
#10931
e5acf910eThanks @phryneas! -useMutation: also reset internal state on reset
-
- 3.8.72 Nov 2023
Release notes
Open source →Patch Changes
-
#11297
c8c76a522Thanks @jerelmiller! - Add an explicit return type for theuseReadQueryhook calledUseReadQueryResult. Previously the return type of this hook was inferred from the return value. -
#11337
bb1da8349Thanks @phryneas! - #11206 used the TypeScript syntaxinfer X extends Ythat was introduced in TS 4.8. This caused some problems for some users, so we are rolling back to a more backwards-compatible (albeit slightly less performant) type.
Additional notes2 sources agree
Open source →Patch Changes
-
#11297
c8c76a522Thanks @jerelmiller! - Add an explicit return type for theuseReadQueryhook calledUseReadQueryResult. Previously the return type of this hook was inferred from the return value. -
#11337
bb1da8349Thanks @phryneas! - #11206 used the TypeScript syntaxinfer X extends Ythat was introduced in TS 4.8. This caused some problems for some users, so we are rolling back to a more backwars-compatible (albeit slightly less performant) type.
-
- 3.8.616 Oct 2023
Release notes3 sources agree
Open source →Patch Changes
-
#11291
2be7eafe3Thanks @ArioA! - Fix a bug that allows to only callloadErrorMessageswithout also callingloadDevErrorMessages. -
#11274
b29f000f3Thanks @jerelmiller! - Start the query ref auto dispose timeout after the initial promise has settled. This prevents requests that run longer than the timeout duration from keeping the component suspended indefinitely. -
#11289
b5894dbf0Thanks @phryneas! -MockedProvider: defaultconnectToDevToolstofalsein createdApolloClientinstance.This will prevent the mocked
ApolloClientinstance from trying to connect to the DevTools, which would start asetTimeoutthat might keep running after a test has finished. -
#11206
dd2ce7687Thanks @phryneas! -cache.modify: Less strict types & new dev runtime warnings.
-
- 3.8.55 Oct 2023
Release notes3 sources agree
Open source →Patch Changes
-
#11266
5192cf6e1Thanks @phryneas! - Fixes argument handling for invariant log messages. -
#11235
6cddaaf65Thanks @phryneas! - Fix nextFetchPolicy behaviour with transformed documents by keepingoptionsreference stable when passing it through QueryManager. -
#11252
327a2abbdThanks @phryneas! - Fixes a race condition in asyncMap that caused issues in React Native when errors were returned in the response payload along with a data property that was null. -
#11229
c372bad4eThanks @phryneas! - Remove (already throwing) SuspenseCache export that should have been removed in 3.8.
-
- 3.8.419 Sept 2023
- 3.8.35 Sept 2023
- 3.8.21 Sept 2023
Release notes3 sources agree
Open source →Patch Changes
-
#10072
51045c336Thanks @Huulivoide! - Fixes race conditions in useReactiveVar that may prevent updates to the reactive variable from propagating through the hook. -
#11162
d9685f53cThanks @jerelmiller! - Ensures GraphQL errors returned in subscription payloads adhere to theerrorPolicyset inclient.subscribe(...)calls. -
#11134
96492e142Thanks @alessbell! - Use separate type imports in useSuspenseQuery and useBackgroundQuery to workaround SWC compiler issue. -
#11117
6b8198109Thanks @phryneas! - Adds a new devtools registration mechanism and tweaks the mechanism behind the "devtools not found" mechanic. -
#11186
f1d429f32Thanks @jerelmiller! - Fix an issue where race conditions when rapidly switching between variables would sometimes result in the wrongdatareturned from the query. Specifically this occurs when a query is triggered with an initial set of variables (VariablesA), then triggers the same query with another set of variables (VariablesB) but switches back to theVariablesAbefore the response forVariablesBis returned. Previously this would result in the data forVariablesBto be displayed whileVariablesAwas active. The data is forVariablesAis now properly returned. -
#11163
a8a9e11e9Thanks @bignimbus! - Fix typo in error message: "occured" -> "occurred" -
#11180
7d9c481e5Thanks @jerelmiller! - Fixes an issue where refetching fromuseBackgroundQueryviarefetchwith an error after an error was already fetched would get stuck in a loading state.
-
- 3.8.110 Aug 2023
Release notes3 sources agree
Open source →Patch Changes
-
#11141
c469b1616Thanks @jerelmiller! - Remove newly exported response iterator helpers that caused problems on some installs where@types/nodewas not available.IMPORTANT
The following exports were added in version 3.8.0 that are removed with this patch.
isAsyncIterableIteratorisBlobisNodeReadableStreamisNodeResponseisReadableStreamisStreamableBlob
-
- 3.8.07 Aug 2023
Release notes
Open source →Minor Changes
Fetching with Suspense 🎉
-
#10323
64cb88a4bThanks @jerelmiller! - Add support for React suspense with a newuseSuspenseQueryhook.useSuspenseQueryinitiates a network request and causes the component calling it to suspend while the request is in flight. It can be thought of as a drop-in replacement foruseQuerythat allows you to take advantage of React's concurrent features while fetching during render.Consider a
Dogcomponent that fetches and renders some information about a dog named Mozzarella:<details> <summary>View code 🐶</summary>
import { Suspense } from 'react'; import { gql, TypedDocumentNode, useSuspenseQuery } from '@apollo/client'; interface Data { dog: { id: string; name: string; }; } interface Variables { name: string; } const GET_DOG_QUERY: TypedDocumentNode<Data, Variables> = gql` query GetDog($name: String) { dog(name: $name) { id name } } `; function App() { return ( <Suspense fallback={<div>Loading...</div>}> <Dog name="Mozzarella" /> </Suspense> ); } function Dog({ name }: { name: string }) { const { data } = useSuspenseQuery(GET_DOG_QUERY, { variables: { name }, }); return <>Name: {data.dog.name}</>; }</details>
For a detailed explanation of
useSuspenseQuery, see our fetching with Suspense reference. -
#10755
e3c676debThanks @alessbell! - Feature: addsuseBackgroundQueryanduseReadQueryhooksuseBackgroundQueryinitiates a request for data in a parent component and returns aQueryReferencewhich is used to read the data in a child component viauseReadQuery. If the child component attempts to render before the data can be found in the cache, the child component will suspend until the data is available. On cache updates to watched data, the child component callinguseReadQuerywill re-render with new data but the parent component will not re-render (as it would, for example, if it were usinguseQueryto issue the request).Consider an
Appcomponent that fetches a list of breeds in the background while also fetching and rendering some information about an individual dog, Mozzarella:<details> <summary>View code 🐶</summary>
function App() { const [queryRef] = useBackgroundQuery(GET_BREEDS_QUERY); return ( <Suspense fallback={<div>Loading...</div>}> <Dog name="Mozzarella" queryRef={queryRef} /> </Suspense> ); } function Dog({ name, queryRef, }: { name: string; queryRef: QueryReference<BreedData>; }) { const { data } = useSuspenseQuery(GET_DOG_QUERY, { variables: { name }, }); return ( <> Name: {data.dog.name} <Suspense fallback={<div>Loading breeds...</div>}> <Breeds queryRef={queryRef} /> </Suspense> </> ); } function Breeds({ queryRef }: { queryRef: QueryReference<BreedData> }) { const { data } = useReadQuery(queryRef); return data.breeds.map(({ characteristics }) => characteristics.map((characteristic) => ( <div key={characteristic}>{characteristic}</div> )) ); }</details>
For a detailed explanation of
useBackgroundQueryanduseReadQuery, see our fetching with Suspense reference.
Document transforms 📑
-
#10509
79df2c7baThanks @jerelmiller! - Add the ability to specify custom GraphQL document transforms. These transforms are run before reading data from the cache, before local state is resolved, and before the query document is sent through the link chain.To register a custom document transform, create a transform using the
DocumentTransformclass and pass it to thedocumentTransformoption onApolloClient.import { DocumentTransform } from "@apollo/client"; const documentTransform = new DocumentTransform((document) => { // do something with `document` return transformedDocument; }); const client = new ApolloClient({ documentTransform: documentTransform });For more information on the behavior and API of
DocumentTransform, see its reference page in our documentation.
New
removeTypenameFromVariableslink 🔗-
#10853
300957960Thanks @jerelmiller! - Introduce the newremoveTypenameFromVariableslink. This link will automatically remove__typenamefields fromvariablesfor all operations. This link can be configured to exclude JSON-scalars for scalars that utilize__typename.This change undoes some work from #10724 where
__typenamewas automatically stripped for all operations with no configuration. This was determined to be a breaking change and therefore moved into this link.For a detailed explanation of
removeTypenameFromVariables, see its API reference.
New
skipTokensentinel ⏭️-
#11112
b4aefcfe9Thanks @jerelmiller! - Adds support for askipTokensentinel that can be used asoptionsinuseSuspenseQueryanduseBackgroundQueryto skip execution of a query. This works identically to theskipoption but is more type-safe and as such, becomes the recommended way to skip query execution. As such, theskipoption has been deprecated in favor ofskipToken.We are considering the removal of the
skipoption fromuseSuspenseQueryanduseBackgroundQueryin the next major. We are releasing with it now to make migration fromuseQueryeasier and makeskipTokenmore discoverable.useSuspenseQueryimport { skipToken, useSuspenseQuery } from "@apollo/client"; const id: number | undefined; const { data } = useSuspenseQuery( query, id ? { variables: { id } } : skipToken );useBackgroundQueryimport { skipToken, useBackgroundQuery } from '@apollo/client'; function Parent() { const [queryRef] = useBackgroundQuery( query, id ? { variables: { id } } : skipToken ); return queryRef ? <Child queryRef={queryRef} /> : null; } function Child({ queryRef }: { queryRef: QueryReference<TData> }) { const { data } = useReadQuery(queryRef); }For a detailed explanation of
skipToken, see its API reference.
New error extraction mechanism, smaller bundles 📉
-
#10887
f8c0b965dThanks @phryneas! - Add a new mechanism for Error Extraction to reduce bundle size by including error message texts on an opt-in basis.By default, errors will link to an error page with the entire error message. This replaces "development" and "production" errors and works without additional bundler configuration.
Bundling the text of error messages and development warnings can be enabled as follows:
import { loadErrorMessages, loadDevMessages } from "@apollo/client/dev"; if (process.env.NODE_ENV !== "production") { loadErrorMessages(); loadDevMessages(); }For a detailed explanation, see our reference on reducing bundle size.
New
@nonreactivedirective 🎬-
#10722
c7e60f83dThanks @benjamn! - Implement a@nonreactivedirective for selectively skipping reactive comparisons of query result subtrees.The
@nonreactivedirective can be used to mark query fields or fragment spreads and is used to indicate that changes to the data contained within the subtrees marked@nonreactiveshould not trigger re-rendering. This allows parent components to fetch data to be rendered by their children without re-rendering themselves when the data corresponding with fields marked as@nonreactivechange.Consider an
Appcomponent that fetches and renders a list of ski trails:<details> <summary>View code 🎿</summary>
const TrailFragment = gql` fragment TrailFragment on Trail { name status } `; const ALL_TRAILS = gql` query allTrails { allTrails { id ...TrailFragment @nonreactive } } ${TrailFragment} `; function App() { const { data, loading } = useQuery(ALL_TRAILS); return ( <main> <h2>Ski Trails</h2> <ul> {data?.trails.map((trail) => ( <Trail key={trail.id} id={trail.id} /> ))} </ul> </main> ); }</details>
The
Trailcomponent renders a trail's name and status and allows the user to execute a mutation to toggle the status of the trail between"OPEN"and"CLOSED":<details> <summary>View code 🎿</summary>
const Trail = ({ id }) => { const [updateTrail] = useMutation(UPDATE_TRAIL); const { data } = useFragment({ fragment: TrailFragment, from: { __typename: "Trail", id, }, }); return ( <li key={id}> {data.name} - {data.status} <input checked={data.status === "OPEN" ? true : false} type="checkbox" onChange={(e) => { updateTrail({ variables: { trailId: id, status: e.target.checked ? "OPEN" : "CLOSED", }, }); }} /> </li> ); };</details>
Notice that the
Trailcomponent isn't receiving the entiretrailobject via props, only theidwhich is used along with the fragment document to create a live binding for each trail item in the cache. This allows eachTrailcomponent to react to the cache updates for a single trail independently. Updates to a trail'sstatuswill not cause the parentAppcomponent to rerender since the@nonreactivedirective is applied to theTrailFragmentspread, a fragment that includes thestatusfield.For a detailed explanation, see our
@nonreactivereference and @alessbell's post on the Apollo blog about using@nonreactivewithuseFragment.
Abort the
AbortControllersignal more granularly 🛑-
#11040
125ef5b2aThanks @phryneas! -HttpLink/BatchHttpLink: Abort theAbortControllersignal more granularly.Before this change, when
HttpLink/BatchHttpLinkcreated anAbortControllerinternally, the signal would always be.aborted after the request was completed. This could cause issues with Sentry Session Replay and Next.js App Router Cache invalidations, which just replayed the fetch with the same options - including the cancelledAbortSignal.With this change, the
AbortControllerwill only be.abort()ed by outside events, not as a consequence of the request completing.
useFragmentdrops its experimental label 🎓-
#10916
ea75e18deThanks @alessbell! - Remove experimental labels.useFragment, introduced in3.7.0asuseFragment_experimental, is no longer an experimental API 🎉 We've removed the_experimentalsuffix from its named export and have made a number of improvements.For a detailed explanation, see our
useFragmentreference and @alessbell's post on the Apollo blog about usinguseFragmentwith@nonreactivefor improved performance when rendering lists.<details> <summary><h5><code>useFragment</code> improvements</h5></summary>
-
#10765
35f36c5aaThanks @phryneas! - More robust types for thedataproperty onUseFragmentResult. When a partial result is given, the type is now correctly set toPartial<TData>. -
#11083
f766e8305Thanks @phryneas! - Adjust the rerender timing ofuseQueryto more closely align withuseFragment. This means that cache updates delivered to both hooks should trigger renders at relatively the same time. Previously, theuseFragmentmight rerender much faster leading to some confusion. -
#10836
6794893c2Thanks @phryneas! - Remove the deprecatedreturnPartialDataoption fromuseFragmenthook.
</details>
-
<details open> <summary><h4>More Minor Changes</h4></summary>
-
#10895
e187866fdThanks @Gelio! - Add generic type parameter for the entity modified incache.modify. Improves TypeScript type inference for that type's fields and values of those fields.Example:
cache.modify<Book>({ id: cache.identify(someBook), fields: { title: (title) => { // title has type `string`. // It used to be `any`. }, => { // author has type `Reference | Book["author"]`. // It used to be `any`. }, }, }); -
#10895
e187866fdThanks @Gelio! - Use unique opaque types for theDELETEandINVALIDATEApollo cache modifiers.This increases type safety, since these 2 modifiers no longer have the
anytype. Moreover, it no longer triggers the@typescript-eslint/no-unsafe-returnrule. -
#10340
4f73c5ca1Thanks @alessbell! - Avoid callinguseQueryonCompletedfor cache writes -
#10527
0cc7e2e19Thanks @phryneas! - Remove thequery/mutation/subscriptionoption from hooks that already take that value as their first argument. -
#10506
2dc2e1d4fThanks @phryneas! - prevent accidental widening of inferredTDataandTVariablesgenerics for query hook option arguments -
#10521
fbf729414Thanks @benjamn! - Simplify__DEV__polyfill to use imports instead of global scope -
#10994
2ebbd3abbThanks @phryneas! - Add .js file extensions to imports in src and dist/*/.d.ts -
#11045
9c1d4a104Thanks @jerelmiller! - When changing variables back to a previously used set of variables, do not automatically cache the result as part of the query reference. Instead, dispose of the query reference so that theInMemoryCachecan determine the cached behavior. This means that fetch policies that would guarantee a network request are now honored when switching back to previously used variables. -
#11058
89bf33c42Thanks @phryneas! - (Batch)HttpLink: PropagateAbortErrors to the user when a user-providedsignalis passed to the link. Previously, these links would swallow allAbortErrors, potentially causing queries and mutations to never resolve. As a result of this change, users are now expected to handleAbortErrors when passing in a user-providedsignal. -
#10346
3bcfc42d3Thanks @jerelmiller! - Add the ability to allow@clientfields to be sent to the link chain. -
#10567
c2ce6496cThanks @benjamn! - AllowApolloCacheimplementations to specify default value forassumeImmutableResultsclient option, improving performance for applications currently usingInMemoryCachewithout configuringnew ApolloClient({ assumeImmutableResults: true }) -
#10915
3a62d8228Thanks @phryneas! - Changes how development-only code is bundled in the library to more reliably enable consuming bundlers to reduce production bundle sizes while keeping compatibility with non-node environments.
</details>
<details open> <summary><h3>Patch Changes</h3></summary>
-
#11086
0264fee06Thanks @jerelmiller! - Fix an issue where a call torefetch,fetchMore, or changingskiptofalsethat returned a result deeply equal to data in the cache would get stuck in a pending state and never resolve. -
#11053
c0ca70720Thanks @phryneas! - AddSuspenseCacheas a lazy hidden property on ApolloClient. This means thatSuspenseCacheis now an implementation details of Apollo Client and you no longer need to manually instantiate it and no longer need to pass it intoApolloProvider. Trying to instantiate aSuspenseCacheinstance in your code will now throw an error. -
#11115
78739e3efThanks @phryneas! - Enforceexport typefor all type-level exports. -
#11027
e47cfd04eThanks @phryneas! - Prevents the DevTool installation warning to be turned into a documentation link. -
#10594
f221b5e8fThanks @phryneas! - Add asuspenseCacheoption touseSuspenseQuery -
#10700
12e37f46fThanks @jerelmiller! - Add aqueryKeyoption touseSuspenseQuerythat allows the hook to create a unique subscription instance. -
#10724
e285dfd00Thanks @jerelmiller! - Automatically strips__typenamefields fromvariablessent to the server when usingHttpLink,BatchHttpLink, orGraphQLWsLink. This allows GraphQL data returned from a query to be used as an argument to a subsequent GraphQL operation without the need to strip the__typenamein user-space. -
#10957
445164d21Thanks @phryneas! - UseReact.versionas key for shared Contexts. -
#10635
7df51ee19Thanks @jerelmiller! - Fix an issue where cache updates would not propagate touseSuspenseQuerywhile in strict mode. -
#11013
5ed2cfdafThanks @alessbell! - Make private fieldsinFlightLinkObservablesandfetchCancelFnsprotected in QueryManager in order to make types available in@apollo/experimental-nextjs-app-supportpackage when extending theApolloClientclass. -
#10869
ba1d06166Thanks @phryneas! - Ensure Context value stability when rerendering ApolloProvider with the sameclientand/orsuspenseCacheprop -
#11103
e3d611dafThanks @caylahamann! - Fixes a bug inuseMutationso thatonErroris called when an error is returned from the request witherrorPolicyset to 'all' . -
#10657
db305a800Thanks @jerelmiller! - ReturnnetworkStatusin theuseSuspenseQueryresult. -
#10937
eea44eb87Thanks @jerelmiller! - MovesDocumentTransformto theutilitiessub-package to avoid a circular dependency between thecoreandcachesub-packages. -
#10951
2e833b2caThanks @alessbell! - ImproveuseBackgroundQuerytype interface -
#10651
8355d0e1eThanks @jerelmiller! - Fixes an issue whereuseSuspenseQuerywould not respond to cache updates when using a cache-firstfetchPolicyafter the hook was mounted with data already in the cache. -
#11026
b8d405eeeThanks @phryneas! - Store React.Context instance mapped by React.createContext instance, not React.version. UsingReact.versioncan cause problems withpreact, as multiple versions ofpreactwill all identify themselves as React17.0.2. -
#11000
1d43ab616Thanks @phryneas! - Useimport * as Reacteverywhere. This prevents an error when importing@apollo/clientin a React Server component. (see #10974) -
#10852
27fbdb3f9Thanks @phryneas! - Chore: Add ESLint rule for consistent type imports, apply autofix -
#10999
c1904a78aThanks @phryneas! - Fix a bug inQueryReferencewherethis.resolveorthis.rejectmight be executed even ifundefined. -
#10940
1d38f128fThanks @jerelmiller! - Add support for theskipoption inuseBackgroundQueryanduseSuspenseQuery. Setting this option totruewill avoid a network request. -
#10672
932252b0cThanks @jerelmiller! - Fix the compatibility betweenuseSuspenseQueryand React'suseDeferredValueandstartTransitionAPIs to allow React to show stale UI while the changes to the variable cause the component to suspend.Breaking change
nextFetchPolicysupport has been removed fromuseSuspenseQuery. If you are using this option, remove it, otherwise it will be ignored. -
#10964
f33171506Thanks @alessbell! - Fixes a bug inBatchHttpLinkthat removed variables from all requests by default. -
#10633
90a06eeebThanks @benjamn! - Fix type policy inheritance involving fuzzypossibleTypes -
#10754
64b304862Thanks @sincraianul! - FixincludeUnusedVariablesoption not working withBatchHttpLink -
#11018
5618953f3Thanks @jerelmiller! -useBackgroundQuerynow uses its own options type calledBackgroundQueryHookOptionsrather than reusingSuspenseQueryHookOptions. -
#11035
a3ab7456dThanks @jerelmiller! - Incrementally re-render deferred queries after callingrefetchor settingskiptofalseto match the behavior of the initial fetch. Previously, the hook would not re-render until the entire result had finished loading in these cases. -
#10399
652a1ae08Thanks @alessbell! - Silence useLayoutEffect warning when useSuspenseQuery runs on server -
#10919
f796ce1acThanks @jerelmiller! - Fix an issue when using a link that relied onoperation.getContextandoperation.setContextwould error out when it was declared after theremoveTypenameFromVariableslink. -
#10968
b102390b2Thanks @phryneas! - Use printed query for query deduplication. Cacheprintcalls for GraphQL documents to speed up repeated operations. -
#11071
4473e925aThanks @jerelmiller! - #10509 introduced some helpers for determining the type of operation for a GraphQL query. This imported theOperationTypeNodefrom graphql-js which is not available in GraphQL 14. To maintain compatibility with graphql-js v14, this has been reverted to use plain strings. -
#10766
ffb179e55Thanks @jerelmiller! - More robust typings for thedataproperty returned fromuseSuspenseQuerywhen usingreturnPartialData: trueor anerrorPolicyofallorignore.TDatanow defaults tounknowninstead ofany. -
#10401
3e5b41a75Thanks @jerelmiller! - Always throw network errors inuseSuspenseQueryregardless of the seterrorPolicy. -
#10877
f40248598Thanks @phryneas! - Change an import inuseQueryanduseMutationthat added an unnecessary runtime dependency on@apollo/client/core. This drastically reduces the bundle size of each the hooks. -
#10656
54c4d2f3cThanks @jerelmiller! - Ensurerefetch,fetchMore, andsubscribeToMorefunctions returned byuseSuspenseQueryare referentially stable between renders, even asdatais updated. -
#10324
95eb228beThanks @jerelmiller! - Add@defersupport touseSuspenseQuery. -
#10888
1562a2f5aThanks @alessbell! - Updates dependency versions inpackage.jsonby bumping:@wry/contextto^0.7.3@wry/equalityto^0.5.6@wry/trieto^0.4.3optimismto^0.17.4
to 1. fix sourcemap warnings and 2. a Codesandbox sandpack (in-browser) bundler transpilation bug with an upstream optimism workaround.
-
#11010
1051a9c88Thanks @alessbell! - Hide queryRef in a Symbol inuseBackgroundQuerys return value. -
#10758
9def7421fThanks @phryneas! - useReact.usewhere available -
#11032
6a4da900aThanks @jerelmiller! - Throw errors inuseSuspenseQueryfor errors returned in incremental chunks whenerrorPolicyisnone. This provides a more consistent behavior of theerrorPolicyin the hook.Potentially breaking change
Previously, if you issued a query with
@deferand relied onerrorPolicy: 'none'to set theerrorproperty returned fromuseSuspenseQuerywhen the error was returned in an incremental chunk, this error is now thrown. Switch theerrorPolicytoallto avoid throwing the error and instead return it in theerrorproperty. -
#10960
ee407ef97Thanks @alessbell! - Adds support forreturnPartialDataandrefetchWritePolicyoptions inuseBackgroundQueryhook. -
#10809
49d28f764Thanks @jerelmiller! - Fixed the ability to userefetchandfetchMorewith React'sstartTransition. The hook will now behave correctly by allowing React to avoid showing the Suspense fallback when these functions are wrapped bystartTransition. This change deprecates thesuspensePolicyoption in favor ofstartTransition. -
#11082
0f1cde3a2Thanks @phryneas! - Restore Apollo Client 3.7getApolloContextbehaviour -
#10969
525a9317aThanks @phryneas! - Slightly decrease bundle size and memory footprint ofSuspenseCacheby changing how cache entries are stored internally. -
#11025
6092b6edfThanks @jerelmiller! -useSuspenseQueryanduseBackgroundQuerywill now properly apply changes to its options between renders. -
#10872
96b4f8837Thanks @phryneas! - The "per-React-Version-Singleton" ApolloContext is now stored onglobalThis, notReact.createContext, and throws an error message when accessed from React Server Components. -
#10450
f8bc33387Thanks @jerelmiller! - Add support for thesubscribeToMoreandclientfields returned in theuseSuspenseQueryresult.
</details>
Additional notes2 sources agree
Open source →Minor Changes
Fetching with Suspense 🎉
-
#10323
64cb88a4bThanks @jerelmiller! - Add support for React suspense with a newuseSuspenseQueryhook.useSuspenseQueryinitiates a network request and causes the component calling it to suspend while the request is in flight. It can be thought of as a drop-in replacement foruseQuerythat allows you to take advantage of React's concurrent features while fetching during render.Consider a
Dogcomponent that fetches and renders some information about a dog named Mozzarella:<details> <summary>View code 🐶</summary>
import { Suspense } from "react"; import { gql, TypedDocumentNode, useSuspenseQuery } from "@apollo/client"; interface Data { dog: { id: string; name: string; }; } interface Variables { name: string; } const GET_DOG_QUERY: TypedDocumentNode<Data, Variables> = gql` query GetDog($name: String) { dog(name: $name) { id name } } `; function App() { return ( <Suspense fallback={<div>Loading...</div>}> <Dog name="Mozzarella" /> </Suspense> ); } function Dog({ name }: { name: string }) { const { data } = useSuspenseQuery(GET_DOG_QUERY, { variables: { name }, }); return <>Name: {data.dog.name}</>; }</details>
For a detailed explanation of
useSuspenseQuery, see our fetching with Suspense reference. -
#10755
e3c676debThanks @alessbell! - Feature: addsuseBackgroundQueryanduseReadQueryhooksuseBackgroundQueryinitiates a request for data in a parent component and returns aQueryReferencewhich is used to read the data in a child component viauseReadQuery. If the child component attempts to render before the data can be found in the cache, the child component will suspend until the data is available. On cache updates to watched data, the child component callinguseReadQuerywill re-render with new data but the parent component will not re-render (as it would, for example, if it were usinguseQueryto issue the request).Consider an
Appcomponent that fetches a list of breeds in the background while also fetching and rendering some information about an individual dog, Mozzarella:<details> <summary>View code 🐶</summary>
function App() { const [queryRef] = useBackgroundQuery(GET_BREEDS_QUERY); return ( <Suspense fallback={<div>Loading...</div>}> <Dog name="Mozzarella" queryRef={queryRef} /> </Suspense> ); } function Dog({ name, queryRef, }: { name: string; queryRef: QueryReference<BreedData>; }) { const { data } = useSuspenseQuery(GET_DOG_QUERY, { variables: { name }, }); return ( <> Name: {data.dog.name} <Suspense fallback={<div>Loading breeds...</div>}> <Breeds queryRef={queryRef} /> </Suspense> </> ); } function Breeds({ queryRef }: { queryRef: QueryReference<BreedData> }) { const { data } = useReadQuery(queryRef); return data.breeds.map(({ characteristics }) => characteristics.map((characteristic) => ( <div key={characteristic}>{characteristic}</div> )) ); }</details>
For a detailed explanation of
useBackgroundQueryanduseReadQuery, see our fetching with Suspense reference.
Document transforms 📑
-
#10509
79df2c7baThanks @jerelmiller! - Add the ability to specify custom GraphQL document transforms. These transforms are run before reading data from the cache, before local state is resolved, and before the query document is sent through the link chain.To register a custom document transform, create a transform using the
DocumentTransformclass and pass it to thedocumentTransformoption onApolloClient.import { DocumentTransform } from "@apollo/client"; const documentTransform = new DocumentTransform((document) => { // do something with `document` return transformedDocument; }); const client = new ApolloClient({ documentTransform: documentTransform });For more information on the behavior and API of
DocumentTransform, see its reference page in our documentation.
New
removeTypenameFromVariableslink 🔗-
#10853
300957960Thanks @jerelmiller! - Introduce the newremoveTypenameFromVariableslink. This link will automatically remove__typenamefields fromvariablesfor all operations. This link can be configured to exclude JSON-scalars for scalars that utilize__typename.This change undoes some work from #10724 where
__typenamewas automatically stripped for all operations with no configuration. This was determined to be a breaking change and therefore moved into this link.For a detailed explanation of
removeTypenameFromVariables, see its API reference.
New
skipTokensentinel ⏭️-
#11112
b4aefcfe9Thanks @jerelmiller! - Adds support for askipTokensentinel that can be used asoptionsinuseSuspenseQueryanduseBackgroundQueryto skip execution of a query. This works identically to theskipoption but is more type-safe and as such, becomes the recommended way to skip query execution. As such, theskipoption has been deprecated in favor ofskipToken.We are considering the removal of the
skipoption fromuseSuspenseQueryanduseBackgroundQueryin the next major. We are releasing with it now to make migration fromuseQueryeasier and makeskipTokenmore discoverable.useSuspenseQueryimport { skipToken, useSuspenseQuery } from "@apollo/client"; const id: number | undefined; const { data } = useSuspenseQuery( query, id ? { variables: { id } } : skipToken );useBackgroundQueryimport { skipToken, useBackgroundQuery } from "@apollo/client"; function Parent() { const [queryRef] = useBackgroundQuery( query, id ? { variables: { id } } : skipToken ); return queryRef ? <Child queryRef={queryRef} /> : null; } function Child({ queryRef }: { queryRef: QueryReference<TData> }) { const { data } = useReadQuery(queryRef); }For a detailed explanation of
skipToken, see its API reference.
New error extraction mechanism, smaller bundles 📉
-
#10887
f8c0b965dThanks @phryneas! - Add a new mechanism for Error Extraction to reduce bundle size by including error message texts on an opt-in basis.By default, errors will link to an error page with the entire error message. This replaces "development" and "production" errors and works without additional bundler configuration.
Bundling the text of error messages and development warnings can be enabled as follows:
import { loadErrorMessages, loadDevMessages } from "@apollo/client/dev"; if (process.env.NODE_ENV !== "production") { loadErrorMessages(); loadDevMessages(); }For a detailed explanation, see our reference on reducing bundle size.
New
@nonreactivedirective 🎬-
#10722
c7e60f83dThanks @benjamn! - Implement a@nonreactivedirective for selectively skipping reactive comparisons of query result subtrees.The
@nonreactivedirective can be used to mark query fields or fragment spreads and is used to indicate that changes to the data contained within the subtrees marked@nonreactiveshould not trigger re-rendering. This allows parent components to fetch data to be rendered by their children without re-rendering themselves when the data corresponding with fields marked as@nonreactivechange.Consider an
Appcomponent that fetches and renders a list of ski trails:<details> <summary>View code 🎿</summary>
const TrailFragment = gql` fragment TrailFragment on Trail { name status } `; const ALL_TRAILS = gql` query allTrails { allTrails { id ...TrailFragment @nonreactive } } ${TrailFragment} `; function App() { const { data, loading } = useQuery(ALL_TRAILS); return ( <main> <h2>Ski Trails</h2> <ul> {data?.trails.map((trail) => ( <Trail key={trail.id} id={trail.id} /> ))} </ul> </main> ); }</details>
The
Trailcomponent renders a trail's name and status and allows the user to execute a mutation to toggle the status of the trail between"OPEN"and"CLOSED":<details> <summary>View code 🎿</summary>
const Trail = ({ id }) => { const [updateTrail] = useMutation(UPDATE_TRAIL); const { data } = useFragment({ fragment: TrailFragment, from: { __typename: "Trail", id, }, }); return ( <li key={id}> {data.name} - {data.status} <input checked={data.status === "OPEN" ? true : false} type="checkbox" onChange={(e) => { updateTrail({ variables: { trailId: id, status: e.target.checked ? "OPEN" : "CLOSED", }, }); }} /> </li> ); };</details>
Notice that the
Trailcomponent isn't receiving the entiretrailobject via props, only theidwhich is used along with the fragment document to create a live binding for each trail item in the cache. This allows eachTrailcomponent to react to the cache updates for a single trail independently. Updates to a trail'sstatuswill not cause the parentAppcomponent to rerender since the@nonreactivedirective is applied to theTrailFragmentspread, a fragment that includes thestatusfield.For a detailed explanation, see our
@nonreactivereference and @alessbell's post on the Apollo blog about using@nonreactivewithuseFragment.
Abort the
AbortControllersignal more granularly 🛑-
#11040
125ef5b2aThanks @phryneas! -HttpLink/BatchHttpLink: Abort theAbortControllersignal more granularly.Before this change, when
HttpLink/BatchHttpLinkcreated anAbortControllerinternally, the signal would always be.aborted after the request was completed. This could cause issues with Sentry Session Replay and Next.js App Router Cache invalidations, which just replayed the fetch with the same options - including the cancelledAbortSignal.With this change, the
AbortControllerwill only be.abort()ed by outside events, not as a consequence of the request completing.
useFragmentdrops its experimental label 🎓-
#10916
ea75e18deThanks @alessbell! - Remove experimental labels.useFragment, introduced in3.7.0asuseFragment_experimental, is no longer an experimental API 🎉 We've removed the_experimentalsuffix from its named export and have made a number of improvements.For a detailed explanation, see our
useFragmentreference and @alessbell's post on the Apollo blog about usinguseFragmentwith@nonreactivefor improved performance when rendering lists.<details> <summary><h5><code>useFragment</code> improvements</h5></summary>
-
#10765
35f36c5aaThanks @phryneas! - More robust types for thedataproperty onUseFragmentResult. When a partial result is given, the type is now correctly set toPartial<TData>. -
#11083
f766e8305Thanks @phryneas! - Adjust the rerender timing ofuseQueryto more closely align withuseFragment. This means that cache updates delivered to both hooks should trigger renders at relatively the same time. Previously, theuseFragmentmight rerender much faster leading to some confusion. -
#10836
6794893c2Thanks @phryneas! - Remove the deprecatedreturnPartialDataoption fromuseFragmenthook.
</details>
-
<details open> <summary><h4>More Minor Changes</h4></summary>
-
#10895
e187866fdThanks @Gelio! - Add generic type parameter for the entity modified incache.modify. Improves TypeScript type inference for that type's fields and values of those fields.Example:
cache.modify<Book>({ id: cache.identify(someBook), fields: { title: (title) => { // title has type `string`. // It used to be `any`. }, => { // author has type `Reference | Book["author"]`. // It used to be `any`. }, }, }); -
#10895
e187866fdThanks @Gelio! - Use unique opaque types for theDELETEandINVALIDATEApollo cache modifiers.This increases type safety, since these 2 modifiers no longer have the
anytype. Moreover, it no longer triggers the@typescript-eslint/no-unsafe-returnrule. -
#10340
4f73c5ca1Thanks @alessbell! - Avoid callinguseQueryonCompletedfor cache writes -
#10527
0cc7e2e19Thanks @phryneas! - Remove thequery/mutation/subscriptionoption from hooks that already take that value as their first argument. -
#10506
2dc2e1d4fThanks @phryneas! - prevent accidental widening of inferredTDataandTVariablesgenerics for query hook option arguments -
#10521
fbf729414Thanks @benjamn! - Simplify__DEV__polyfill to use imports instead of global scope -
#10994
2ebbd3abbThanks @phryneas! - Add .js file extensions to imports in src and dist/*/.d.ts -
#11045
9c1d4a104Thanks @jerelmiller! - When changing variables back to a previously used set of variables, do not automatically cache the result as part of the query reference. Instead, dispose of the query reference so that theInMemoryCachecan determine the cached behavior. This means that fetch policies that would guarantee a network request are now honored when switching back to previously used variables. -
#11058
89bf33c42Thanks @phryneas! - (Batch)HttpLink: PropagateAbortErrors to the user when a user-providedsignalis passed to the link. Previously, these links would swallow allAbortErrors, potentially causing queries and mutations to never resolve. As a result of this change, users are now expected to handleAbortErrors when passing in a user-providedsignal. -
#10346
3bcfc42d3Thanks @jerelmiller! - Add the ability to allow@clientfields to be sent to the link chain. -
#10567
c2ce6496cThanks @benjamn! - AllowApolloCacheimplementations to specify default value forassumeImmutableResultsclient option, improving performance for applications currently usingInMemoryCachewithout configuringnew ApolloClient({ assumeImmutableResults: true }) -
#10915
3a62d8228Thanks @phryneas! - Changes how development-only code is bundled in the library to more reliably enable consuming bundlers to reduce production bundle sizes while keeping compatibility with non-node environments.
</details>
<details open> <summary><h3>Patch Changes</h3></summary>
-
#11086
0264fee06Thanks @jerelmiller! - Fix an issue where a call torefetch,fetchMore, or changingskiptofalsethat returned a result deeply equal to data in the cache would get stuck in a pending state and never resolve. -
#11053
c0ca70720Thanks @phryneas! - AddSuspenseCacheas a lazy hidden property on ApolloClient. This means thatSuspenseCacheis now an implementation details of Apollo Client and you no longer need to manually instantiate it and no longer need to pass it intoApolloProvider. Trying to instantiate aSuspenseCacheinstance in your code will now throw an error. -
#11115
78739e3efThanks @phryneas! - Enforceexport typefor all type-level exports. -
#11027
e47cfd04eThanks @phryneas! - Prevents the DevTool installation warning to be turned into a documentation link. -
#10594
f221b5e8fThanks @phryneas! - Add asuspenseCacheoption touseSuspenseQuery -
#10700
12e37f46fThanks @jerelmiller! - Add aqueryKeyoption touseSuspenseQuerythat allows the hook to create a unique subscription instance. -
#10724
e285dfd00Thanks @jerelmiller! - Automatically strips__typenamefields fromvariablessent to the server when usingHttpLink,BatchHttpLink, orGraphQLWsLink. This allows GraphQL data returned from a query to be used as an argument to a subsequent GraphQL operation without the need to strip the__typenamein user-space. -
#10957
445164d21Thanks @phryneas! - UseReact.versionas key for shared Contexts. -
#10635
7df51ee19Thanks @jerelmiller! - Fix an issue where cache updates would not propagate touseSuspenseQuerywhile in strict mode. -
#11013
5ed2cfdafThanks @alessbell! - Make private fieldsinFlightLinkObservablesandfetchCancelFnsprotected in QueryManager in order to make types available in@apollo/experimental-nextjs-app-supportpackage when extending theApolloClientclass. -
#10869
ba1d06166Thanks @phryneas! - Ensure Context value stability when rerendering ApolloProvider with the sameclientand/orsuspenseCacheprop -
#11103
e3d611dafThanks @caylahamann! - Fixes a bug inuseMutationso thatonErroris called when an error is returned from the request witherrorPolicyset to 'all' . -
#10657
db305a800Thanks @jerelmiller! - ReturnnetworkStatusin theuseSuspenseQueryresult. -
#10937
eea44eb87Thanks @jerelmiller! - MovesDocumentTransformto theutilitiessub-package to avoid a circular dependency between thecoreandcachesub-packages. -
#10951
2e833b2caThanks @alessbell! - ImproveuseBackgroundQuerytype interface -
#10651
8355d0e1eThanks @jerelmiller! - Fixes an issue whereuseSuspenseQuerywould not respond to cache updates when using a cache-firstfetchPolicyafter the hook was mounted with data already in the cache. -
#11026
b8d405eeeThanks @phryneas! - Store React.Context instance mapped by React.createContext instance, not React.version. UsingReact.versioncan cause problems withpreact, as multiple versions ofpreactwill all identify themselves as React17.0.2. -
#11000
1d43ab616Thanks @phryneas! - Useimport * as Reacteverywhere. This prevents an error when importing@apollo/clientin a React Server component. (see #10974) -
#10852
27fbdb3f9Thanks @phryneas! - Chore: Add ESLint rule for consistent type imports, apply autofix -
#10999
c1904a78aThanks @phryneas! - Fix a bug inQueryReferencewherethis.resolveorthis.rejectmight be executed even ifundefined. -
#10940
1d38f128fThanks @jerelmiller! - Add support for theskipoption inuseBackgroundQueryanduseSuspenseQuery. Setting this option totruewill avoid a network request. -
#10672
932252b0cThanks @jerelmiller! - Fix the compatibility betweenuseSuspenseQueryand React'suseDeferredValueandstartTransitionAPIs to allow React to show stale UI while the changes to the variable cause the component to suspend.Breaking change
nextFetchPolicysupport has been removed fromuseSuspenseQuery. If you are using this option, remove it, otherwise it will be ignored. -
#10964
f33171506Thanks @alessbell! - Fixes a bug inBatchHttpLinkthat removed variables from all requests by default. -
#10633
90a06eeebThanks @benjamn! - Fix type policy inheritance involving fuzzypossibleTypes -
#10754
64b304862Thanks @sincraianul! - FixincludeUnusedVariablesoption not working withBatchHttpLink -
#11018
5618953f3Thanks @jerelmiller! -useBackgroundQuerynow uses its own options type calledBackgroundQueryHookOptionsrather than reusingSuspenseQueryHookOptions. -
#11035
a3ab7456dThanks @jerelmiller! - Incrementally re-render deferred queries after callingrefetchor settingskiptofalseto match the behavior of the initial fetch. Previously, the hook would not re-render until the entire result had finished loading in these cases. -
#10399
652a1ae08Thanks @alessbell! - Silence useLayoutEffect warning when useSuspenseQuery runs on server -
#10919
f796ce1acThanks @jerelmiller! - Fix an issue when using a link that relied onoperation.getContextandoperation.setContextwould error out when it was declared after theremoveTypenameFromVariableslink. -
#10968
b102390b2Thanks @phryneas! - Use printed query for query deduplication. Cacheprintcalls for GraphQL documents to speed up repeated operations. -
#11071
4473e925aThanks @jerelmiller! - #10509 introduced some helpers for determining the type of operation for a GraphQL query. This imported theOperationTypeNodefrom graphql-js which is not available in GraphQL 14. To maintain compatibility with graphql-js v14, this has been reverted to use plain strings. -
#10766
ffb179e55Thanks @jerelmiller! - More robust typings for thedataproperty returned fromuseSuspenseQuerywhen usingreturnPartialData: trueor anerrorPolicyofallorignore.TDatanow defaults tounknowninstead ofany. -
#10401
3e5b41a75Thanks @jerelmiller! - Always throw network errors inuseSuspenseQueryregardless of the seterrorPolicy. -
#10877
f40248598Thanks @phryneas! - Change an import inuseQueryanduseMutationthat added an unnecessary runtime dependency on@apollo/client/core. This drastically reduces the bundle size of each the hooks. -
#10656
54c4d2f3cThanks @jerelmiller! - Ensurerefetch,fetchMore, andsubscribeToMorefunctions returned byuseSuspenseQueryare referentially stable between renders, even asdatais updated. -
#10324
95eb228beThanks @jerelmiller! - Add@defersupport touseSuspenseQuery. -
#10888
1562a2f5aThanks @alessbell! - Updates dependency versions inpackage.jsonby bumping:@wry/contextto^0.7.3@wry/equalityto^0.5.6@wry/trieto^0.4.3optimismto^0.17.4
to 1. fix sourcemap warnings and 2. a Codesandbox sandpack (in-browser) bundler transpilation bug with an upstream optimism workaround.
-
#11010
1051a9c88Thanks @alessbell! - Hide queryRef in a Symbol inuseBackgroundQuerys return value. -
#10758
9def7421fThanks @phryneas! - useReact.usewhere available -
#11032
6a4da900aThanks @jerelmiller! - Throw errors inuseSuspenseQueryfor errors returned in incremental chunks whenerrorPolicyisnone. This provides a more consistent behavior of theerrorPolicyin the hook.Potentially breaking change
Previously, if you issued a query with
@deferand relied onerrorPolicy: 'none'to set theerrorproperty returned fromuseSuspenseQuerywhen the error was returned in an incremental chunk, this error is now thrown. Switch theerrorPolicytoallto avoid throwing the error and instead return it in theerrorproperty. -
#10960
ee407ef97Thanks @alessbell! - Adds support forreturnPartialDataandrefetchWritePolicyoptions inuseBackgroundQueryhook. -
#10809
49d28f764Thanks @jerelmiller! - Fixed the ability to userefetchandfetchMorewith React'sstartTransition. The hook will now behave correctly by allowing React to avoid showing the Suspense fallback when these functions are wrapped bystartTransition. This change deprecates thesuspensePolicyoption in favor ofstartTransition. -
#11082
0f1cde3a2Thanks @phryneas! - Restore Apollo Client 3.7getApolloContextbehaviour -
#10969
525a9317aThanks @phryneas! - Slightly decrease bundle size and memory footprint ofSuspenseCacheby changing how cache entries are stored internally. -
#11025
6092b6edfThanks @jerelmiller! -useSuspenseQueryanduseBackgroundQuerywill now properly apply changes to its options between renders. -
#10872
96b4f8837Thanks @phryneas! - The "per-React-Version-Singleton" ApolloContext is now stored onglobalThis, notReact.createContext, and throws an error message when accessed from React Server Components. -
#10450
f8bc33387Thanks @jerelmiller! - Add support for thesubscribeToMoreandclientfields returned in theuseSuspenseQueryresult.
</details>
-
- 3.8.0-rc.21 Aug 2023pre-release
Release notes
Open source →3.8.0-rc.2
Minor Changes
-
#11112
b4aefcfe9Thanks @jerelmiller! - Adds support for askipTokensentinel that can be used asoptionsinuseSuspenseQueryanduseBackgroundQueryto skip execution of a query. This works identically to theskipoption but is more type-safe and as such, becomes the recommended way to skip query execution. As such, theskipoption has been deprecated in favor ofskipToken.We are considering the removal of the
skipoption fromuseSuspenseQueryanduseBackgroundQueryin the next major. We are releasing with it now to make migration fromuseQueryeasier and makeskipTokenmore discoverable.import { skipToken } from "@apollo/client"; const id: number | undefined; const { data } = useSuspenseQuery( query, id ? { variables: { id } } : skipToken );Breaking change
Previously
useBackgroundQuerywould always return aqueryRefwhenever query execution was skipped. This behavior been updated to return aqueryRefonly when query execution is enabled. If initializing the hook with it skipped,queryRefis now returned asundefined.To migrate, conditionally render the component that accepts the
queryRefas props.Before
function Parent() { const [queryRef] = useBackgroundQuery(query, skip ? skipToken : undefined); // ^? QueryReference<TData | undefined> return <Child queryRef={queryRef} />; } function Child({ queryRef, }: { queryRef: QueryReference<TData | undefined>; }) { const { data } = useReadQuery(queryRef); }After
function Parent() { const [queryRef] = useBackgroundQuery(query, skip ? skipToken : undefined); // ^? QueryReference<TData> | undefined return queryRef ? <Child queryRef={queryRef} /> : null; } function Child({ queryRef }: { queryRef: QueryReference<TData> }) { const { data } = useReadQuery(queryRef); }
Patch Changes
-
#11086
0264fee06Thanks @jerelmiller! - Fix an issue where a call torefetch,fetchMore, or changingskiptofalsethat returned a result deeply equal to data in the cache would get stuck in a pending state and never resolve. -
#11115
78739e3efThanks @phryneas! - Enforceexport typefor all type-level exports. -
#11103
e3d611dafThanks @caylahamann! - Fixes a bug inuseMutationso thatonErroris called when an error is returned from the request witherrorPolicyset to 'all' . -
#11083
f766e8305Thanks @phryneas! - Adjust the rerender timing ofuseQueryto more closely align withuseFragment. This means that cache updates delivered to both hooks should trigger renders at relatively the same time. Previously, theuseFragmentmight rerender much faster leading to some confusion. -
#11082
0f1cde3a2Thanks @phryneas! - Restore Apollo Client 3.7getApolloContextbehaviour
-
- 3.8.0-rc.117 Jul 2023pre-release
Release notes
Open source →3.8.0-rc.1
Patch Changes
- #11071
4473e925aThanks @jerelmiller! - #10509 introduced some helpers for determining the type of operation for a GraphQL query. This imported theOperationTypeNodefrom graphql-js which is not available in GraphQL 14. To maintain compatibility with graphql-js v14, this has been reverted to use plain strings.
- #11071
- 3.8.0-rc.013 Jul 2023pre-release
Release notes
Open source →3.8.0-rc.0
Minor Changes
-
#11058
89bf33c42Thanks @phryneas! - (Batch)HttpLink: PropagateAbortErrors to the user when a user-providedsignalis passed to the link. Previously, these links would swallow allAbortErrors, potentially causing queries and mutations to never resolve. As a result of this change, users are now expected to handleAbortErrors when passing in a user-providedsignal. -
#11040
125ef5b2aThanks @phryneas! -HttpLink/BatchHttpLink: Abort theAbortControllersignal more granularly. Before this change, whenHttpLink/BatchHttpLinkcreated anAbortControllerinternally, the signal would always be.aborted after the request was completed. This could cause issues with Sentry Session Replay and Next.js App Router Cache invalidations, which just replayed the fetch with the same options - including the cancelledAbortSignal.With this change, the
AbortControllerwill only be.abort()ed by outside events, not as a consequence of the request completing.
Patch Changes
-
#11053
c0ca70720Thanks @phryneas! - AddSuspenseCacheas a lazy hidden property on ApolloClient. This means thatSuspenseCacheis now an implementation details of Apollo Client and you no longer need to manually instantiate it and no longer need to pass it intoApolloProvider. Trying to instantiate aSuspenseCacheinstance in your code will now throw an error.Migration:
-import { SuspenseCache } from '@apollo/client'; -const suspenseCache = new SuspenseCache(); -<ApolloProvider client={client} suspenseCache={suspenseCache} />; +<ApolloProvider client={client} />;
-
- 3.8.0-beta.710 Jul 2023pre-release
Release notes
Open source →3.8.0-beta.7
Minor Changes
-
#10994
2ebbd3abbThanks @phryneas! - Add .js file extensions to imports in src and dist/*/.d.ts -
#11045
9c1d4a104Thanks @jerelmiller! - When changing variables back to a previously used set of variables, do not automatically cache the result as part of the query reference. Instead, dispose of the query reference so that theInMemoryCachecan determine the cached behavior. This means that fetch policies that would guarantee a network request are now honored when switching back to previously used variables. -
#10915
3a62d8228Thanks @phryneas! - Changes how development-only code is bundled in the library to more reliably enable consuming bundlers to reduce production bundle sizes while keeping compatibility with non-node environments.
Patch Changes
-
#11026
b8d405eeeThanks @phryneas! - Store React.Context instance mapped by React.createContext instance, not React.version. UsingReact.versioncan cause problems withpreact, as multiple versions ofpreactwill all identify themselves as React17.0.2. -
#11000
1d43ab616Thanks @phryneas! - Useimport * as Reacteverywhere. This prevents an error when importing@apollo/clientin a React Server component. (see #10974) -
#11035
a3ab7456dThanks @jerelmiller! - Incrementally re-render deferred queries after callingrefetchor settingskiptofalseto match the behavior of the initial fetch. Previously, the hook would not re-render until the entire result had finished loading in these cases.
-
- 3.8.0-beta.65 Jul 2023pre-release
Release notes
Open source →3.8.0-beta.6
Patch Changes
-
#11027
e47cfd04eThanks @phryneas! - Prevents the DevTool installation warning to be turned into a documentation link. -
#11013
5ed2cfdafThanks @alessbell! - Make private fieldsinFlightLinkObservablesandfetchCancelFnsprotected in QueryManager in order to make types available in@apollo/experimental-nextjs-app-supportpackage when extending theApolloClientclass. -
#11032
6a4da900aThanks @jerelmiller! - Throw errors inuseSuspenseQueryfor errors returned in incremental chunks whenerrorPolicyisnone. This provides a more consistent behavior of theerrorPolicyin the hook.Potentially breaking change
Previously, if you issued a query with
@deferand relied onerrorPolicy: 'none'to set theerrorproperty returned fromuseSuspenseQuerywhen the error was returned in an incremental chunk, this error is now thrown. Switch theerrorPolicytoallto avoid throwing the error and instead return it in theerrorproperty. -
#11025
6092b6edfThanks @jerelmiller! -useSuspenseQueryanduseBackgroundQuerywill now properly apply changes to its options between renders.
-
- 3.8.0-beta.528 Jun 2023pre-release
Release notes
Open source →3.8.0-beta.5
Patch Changes
-
#10999
c1904a78aThanks @phryneas! - Fix a bug inQueryReferencewherethis.resolveorthis.rejectmight be executed even ifundefined. -
#11018
5618953f3Thanks @jerelmiller! -useBackgroundQuerynow uses its own options type calledBackgroundQueryHookOptionsrather than reusingSuspenseQueryHookOptions. -
#11010
1051a9c88Thanks @alessbell! - Hide queryRef in a Symbol inuseBackgroundQuerys return value. -
#10960
ee407ef97Thanks @alessbell! - Adds support forreturnPartialDataandrefetchWritePolicyoptions inuseBackgroundQueryhook.
-
- 3.8.0-beta.420 Jun 2023pre-release
Release notes
Open source →3.8.0-beta.4
Patch Changes
- #10940
1d38f128fThanks @jerelmiller! - Add support for theskipoption inuseBackgroundQueryanduseSuspenseQuery. Setting this option totruewill avoid a network request.
- #10940
- 3.8.0-beta.315 Jun 2023pre-release
Release notes
Open source →3.8.0-beta.3
Minor Changes
-
#10895
e187866fdThanks @(author)! - Add generic type parameter for the entity modified incache.modify. Improves TypeScript type inference for that type's fields and values of those fields.Example:
cache.modify<Book>({ id: cache.identify(someBook), fields: { title: (title) => { // title has type `string`. // It used to be `any`. }, => { // author has type `Reference | Book["author"]`. // It used to be `any`. }, }, }); -
#10895
e187866fdThanks @Gelio! - Use unique opaque types for theDELETEandINVALIDATEApollo cache modifiers.This increases type safety, since these 2 modifiers no longer have the
anytype. Moreover, it no longer triggers the@typescript-eslint/no-unsafe-returnrule.
Patch Changes
-
#10951
2e833b2caThanks @alessbell! - ImproveuseBackgroundQuerytype interface -
#10964
f33171506Thanks @alessbell! - Fixes a bug inBatchHttpLinkthat removed variables from all requests by default. -
#10968
b102390b2Thanks @phryneas! - Use printed query for query deduplication. Cacheprintcalls for GraphQL documents to speed up repeated operations. -
#10969
525a9317aThanks @phryneas! - Slightly decrease bundle size and memory footprint ofSuspenseCacheby changing how cache entries are stored internally.
-
- 3.8.0-beta.27 Jun 2023pre-release
- 3.8.0-beta.131 May 2023pre-release
Release notes
Open source →3.8.0-beta.1
Patch Changes
-
#10937
eea44eb87Thanks @jerelmiller! - MovesDocumentTransformto theutilitiessub-package to avoid a circular dependency between thecoreandcachesub-packages. -
#10919
f796ce1acThanks @jerelmiller! - Fix an issue when using a link that relied onoperation.getContextandoperation.setContextwould error out when it was declared after theremoveTypenameFromVariableslink.
-
- 3.8.0-beta.026 May 2023pre-release
Release notes
Open source →3.8.0-beta.0
Minor Changes
-
#10887
f8c0b965dThanks @phryneas! - Add a new mechanism for Error Extraction to reduce bundle size by including error message texts on an opt-in basis. By default, errors will link to an error page with the entire error message. This replaces "development" and "production" errors and works without additional bundler configuration. Bundling the text of error messages and development warnings can be enabled byimport { loadErrorMessages, loadDevMessages } from "@apollo/client/dev"; if (process.env.NODE_ENV !== "production") { loadErrorMessages(); loadDevMessages(); } -
#10509
79df2c7baThanks @jerelmiller! - Add the ability to specify custom GraphQL document transforms. These transforms are run before reading data from the cache, before local state is resolved, and before the query document is sent through the link chain.To register a custom document transform, create a transform using the
DocumentTransformclass and pass it to thedocumentTransformoption onApolloClient.import { DocumentTransform } from "@apollo/client"; const documentTransform = new DocumentTransform((document) => { // do something with `document` return transformedDocument; }); const client = new ApolloClient({ documentTransform: documentTransform });For additional documentation on the behavior and API of
DocumentTransform, see the pull request. -
#10916
ea75e18deThanks @alessbell! - Remove experimental labels from hooks, move to beta.
-
- 3.8.0-alpha.1517 May 2023pre-release
Release notes
Open source →3.8.0-alpha.15
Patch Changes
-
#10888
1562a2f5aThanks @alessbell! - Updates dependency versions inpackage.jsonby bumping:@wry/contextto^0.7.3@wry/equalityto^0.5.6@wry/trieto^0.4.3optimismto^0.17.4
to 1. fix sourcemap warnings and 2. a Codesandbox sandpack (in-browser) bundler transpilation bug with an upstream optimism workaround.
-
- 3.8.0-alpha.1416 May 2023pre-release
Release notes
Open source →3.8.0-alpha.14
Minor Changes
-
#10755
e3c676debThanks @alessbell! - Feature: addsuseBackgroundQueryanduseReadQueryhooks -
#10853
300957960Thanks @jerelmiller! - Introduce the newremoveTypenameFromVariableslink. This link will automatically remove__typenamefields fromvariablesfor all operations. This link can be configured to exclude JSON-scalars for scalars that utilize__typename.This change undoes some work from #10724 where
__typenamewas automatically stripped for all operations with no configuration. This was determined to be a breaking change and therefore moved into this link.
Patch Changes
-
#10869
ba1d06166Thanks @phryneas! - Ensure Context value stability when rerendering ApolloProvider with the sameclientand/orsuspenseCacheprop -
#10789
23a4e1578Thanks @phryneas! - Fix a bug where other fields could be aliased to__typenameorid, in which case an incoming result would be merged into the wrong cache entry. -
#10765
35f36c5aaThanks @phryneas! - More robust types for thedataproperty onUseFragmentResult. When a partial result is given, the type is now correctly set toPartial<TData>. -
#10852
27fbdb3f9Thanks @phryneas! - Chore: Add ESLint rule for consistent type imports, apply autofix -
#10877
f40248598Thanks @phryneas! - Change an import inuseQueryanduseMutationthat added an unnecessary runtime dependency on@apollo/client/core. This drastically reduces the bundle size of each the hooks. -
#10836
6794893c2Thanks @phryneas! - Remove the deprecatedreturnPartialDataoption fromuseFragmenthook. -
#10872
96b4f8837Thanks @phryneas! - The "per-React-Version-Singleton" ApolloContext is now stored onglobalThis, notReact.createContext, and throws an error message when accessed from React Server Components.
-
- 3.8.0-alpha.133 May 2023pre-release
Release notes
Open source →3.8.0-alpha.13
Patch Changes
-
#10766
ffb179e55Thanks @jerelmiller! - More robust typings for thedataproperty returned fromuseSuspenseQuerywhen usingreturnPartialData: trueor anerrorPolicyofallorignore.TDatanow defaults tounknowninstead ofany. -
#10809
49d28f764Thanks @jerelmiller! - Fixed the ability to userefetchandfetchMorewith React'sstartTransition. The hook will now behave correctly by allowing React to avoid showing the Suspense fallback when these functions are wrapped bystartTransition. This change deprecates thesuspensePolicyoption in favor ofstartTransition.
-
- 3.8.0-alpha.1213 Apr 2023pre-release
Release notes
Open source →3.8.0-alpha.12
Minor Changes
- #10722
c7e60f83dThanks @benjamn! - Implement a@nonreactivedirective for selectively skipping reactive comparisons of query result subtrees
Patch Changes
-
#10700
12e37f46fThanks @jerelmiller! - Add aqueryKeyoption touseSuspenseQuerythat allows the hook to create a unique subscription instance. -
#10724
e285dfd00Thanks @jerelmiller! - Automatically strips__typenamefields fromvariablessent to the server when usingHttpLink,BatchHttpLink, orGraphQLWsLink. This allows GraphQL data returned from a query to be used as an argument to a subsequent GraphQL operation without the need to strip the__typenamein user-space. -
#10754
64b304862Thanks @sincraianul! - FixincludeUnusedVariablesoption not working withBatchHttpLink -
#10758
9def7421fThanks @phryneas! - useReact.usewhere available
- #10722
- 3.8.0-alpha.1128 Mar 2023pre-release
Release notes
Open source →3.8.0-alpha.11
Minor Changes
- #10567
c2ce6496cThanks @benjamn! - AllowApolloCacheimplementations to specify default value forassumeImmutableResultsclient option, improving performance for applications currently usingInMemoryCachewithout configuringnew ApolloClient({ assumeImmutableResults: true })
Patch Changes
-
#10672
932252b0cThanks @jerelmiller! - Fix the compatibility betweenuseSuspenseQueryand React'suseDeferredValueandstartTransitionAPIs to allow React to show stale UI while the changes to the variable cause the component to suspend.Breaking change
nextFetchPolicysupport has been removed fromuseSuspenseQuery. If you are using this option, remove it, otherwise it will be ignored.
- #10567
- 3.8.0-alpha.1017 Mar 2023pre-release
Release notes
Open source →3.8.0-alpha.10
Patch Changes
-
#10657
db305a800Thanks @jerelmiller! - ReturnnetworkStatusin theuseSuspenseQueryresult. -
#10651
8355d0e1eThanks @jerelmiller! - Fixes an issue whereuseSuspenseQuerywould not respond to cache updates when using a cache-firstfetchPolicyafter the hook was mounted with data already in the cache. -
#10656
54c4d2f3cThanks @jerelmiller! - Ensurerefetch,fetchMore, andsubscribeToMorefunctions returned byuseSuspenseQueryare referentially stable between renders, even asdatais updated.
-
- 3.8.0-alpha.915 Mar 2023pre-release
Release notes
Open source →3.8.0-alpha.9
Patch Changes
-
#10635
7df51ee19Thanks @jerelmiller! - Fix an issue where cache updates would not propagate touseSuspenseQuerywhile in strict mode. -
#10633
90a06eeebThanks @benjamn! - Fix type policy inheritance involving fuzzypossibleTypes -
#10629
02605bb3cThanks @phryneas! -useQuery: delay unsubscribe to fix race conditions
-
- 3.8.0-alpha.82 Mar 2023pre-release
- 3.8.0-alpha.715 Feb 2023pre-release
- 3.8.0-alpha.67 Feb 2023pre-release
Release notes
Open source →3.8.0-alpha.6
Minor Changes
- #10521
fbf729414Thanks @benjamn! - Simplify__DEV__polyfill to use imports instead of global scope
Patch Changes
- #7555
45562d6faThanks @TheCeloReis! - AddsTVariablesgeneric toGraphQLRequestandMockedResponseinterfaces.
- #10521
- 3.8.0-alpha.519 Jan 2023pre-release
Release notes
Open source →3.8.0-alpha.5
Patch Changes
- #10450
f8bc33387Thanks @jerelmiller! - Add support for thesubscribeToMoreandclientfields returned in theuseSuspenseQueryresult.
- #10450
- 3.8.0-alpha.413 Jan 2023pre-release
Release notes
Open source →3.8.0-alpha.4
Patch Changes
-
#10383
5c5ca9b01Thanks @jerelmiller! - Ensure theonErrorcallback is called when theerrorPolicyis set to "all" and partial data is returned. -
#10401
3e5b41a75Thanks @jerelmiller! - Always throw network errors inuseSuspenseQueryregardless of the seterrorPolicy.
-
- 3.8.0-alpha.33 Jan 2023pre-release
Release notes
Open source →3.8.0-alpha.3
Patch Changes
- #10399
652a1ae08Thanks @alessbell! - Silence useLayoutEffect warning when useSuspenseQuery runs on server
- #10399
- 3.8.0-alpha.221 Dec 2022pre-release
Release notes
Open source →3.8.0-alpha.2
Minor Changes
- #10346
3bcfc42d3Thanks @jerelmiller! - Add the ability to allow@clientfields to be sent to the link chain.
- #10346
- 3.8.0-alpha.121 Dec 2022pre-release
Release notes
Open source →3.8.0-alpha.15
Patch Changes
-
#10888
1562a2f5aThanks @alessbell! - Updates dependency versions inpackage.jsonby bumping:@wry/contextto^0.7.3@wry/equalityto^0.5.6@wry/trieto^0.4.3optimismto^0.17.4
to 1. fix sourcemap warnings and 2. a Codesandbox sandpack (in-browser) bundler transpilation bug with an upstream optimism workaround.
3.8.0-alpha.14
3.8.0-alpha.13
Patch Changes
-
#10766
ffb179e55Thanks @jerelmiller! - More robust typings for thedataproperty returned fromuseSuspenseQuerywhen usingreturnPartialData: trueor anerrorPolicyofallorignore.TDatanow defaults tounknowninstead ofany. -
#10809
49d28f764Thanks @jerelmiller! - Fixed the ability to userefetchandfetchMorewith React'sstartTransition. The hook will now behave correctly by allowing React to avoid showing the Suspense fallback when these functions are wrapped bystartTransition. This change deprecates thesuspensePolicyoption in favor ofstartTransition.
3.8.0-alpha.12
3.8.0-alpha.11
Minor Changes
- #10567
c2ce6496cThanks @benjamn! - AllowApolloCacheimplementations to specify default value forassumeImmutableResultsclient option, improving performance for applications currently usingInMemoryCachewithout configuringnew ApolloClient({ assumeImmutableResults: true })
Patch Changes
-
#10672
932252b0cThanks @jerelmiller! - Fix the compatibility betweenuseSuspenseQueryand React'suseDeferredValueandstartTransitionAPIs to allow React to show stale UI while the changes to the variable cause the component to suspend.Breaking change
nextFetchPolicysupport has been removed fromuseSuspenseQuery. If you are using this option, remove it, otherwise it will be ignored.
3.8.0-alpha.10
3.8.0-alpha.1
Patch Changes
- #10324
95eb228beThanks @jerelmiller! - Add@defersupport touseSuspenseQuery.
-
- 3.8.0-alpha.09 Dec 2022pre-release
Release notes
Open source →3.8.0-alpha.0
Minor Changes
- #10323
64cb88a4bThanks @jerelmiller! - Add support for React suspense with a newuseSuspenseQueryhook.
Patch Changes
- #10340
4f73c5ca1Thanks @alessbell! - Avoid callinguseQueryonCompletedfor cache writes
- #10323
- 3.7.175 Jul 2023
- 3.7.1620 Jun 2023
Release notes
Open source →Patch Changes
-
#10806
cb1540504Thanks @phryneas! - Fix a bug inPersistedQueryLinkthat would cause it to permanently skip persisted queries after a 400 or 500 status code. -
#10807
b32369592Thanks @phryneas! -PersistedQueryLinkwill now also check for error codes inextensions. -
#10982
b9be7a814Thanks @sdeleur-sc! - UpdaterelayStylePaginationto avoid populatingstartCursorwhen only a single cursor is present under theedgesfield. Use that cursor only as theendCursor. -
#10962
772cfa3cbThanks @jerelmiller! - RemoveuseGETForQueriesoption inBatchHttpLink.Optionstype since it is not supported.
Potentially breaking change in
PersistedQueryLinkPreviously, if the
PersistedQueryLinkencountered a single400or500error, it would stop sending any persisted queries in the future. This allowed you to use the link even if a server had no support for persisted queries.We have decided to change this behavior, so now the
PersistedQueryLinkwill only stop trying to send query hashes if the server responds with aPERSISTED_QUERY_NOT_SUPPORTEDerror code as it was unclear whether a400or500status code was in fact because the server did not support persisted queries.If you relied on the previous behaviour, maybe because you were communicating with a server that might or might not support persisted queries, but would return with a different kind of error, you can use the
disableoption callback to override this behavior like this:createPersistedQueryLink({ // ... other options ... disable({ operation }){ const { response } = operation.getContext(); return ( response && response.status && (response.status === 400 || response.status === 500) ); } })Alternatively, consider removing the link entirely when your server does not support persisted queries.
New Contributors
- @sdeleur-sc made their first contribution in https://github.com/apollographql/apollo-client/pull/10982
Additional notes2 sources agree
Open source →Patch Changes
-
#10806
cb1540504Thanks @phryneas! - Fix a bug inPersistedQueryLinkthat would cause it to permanently skip persisted queries after a 400 or 500 status code. -
#10807
b32369592Thanks @phryneas! -PersistedQueryLinkwill now also check for error codes inextensions. -
#10982
b9be7a814Thanks @sdeleur-sc! - UpdaterelayStylePaginationto avoid populatingstartCursorwhen only a single cursor is present under theedgesfield. Use that cursor only as theendCursor. -
#10962
772cfa3cbThanks @jerelmiller! - RemoveuseGETForQueriesoption inBatchHttpLink.Optionstype since it is not supported.
-
- 3.7.1526 May 2023
Release notes
Open source →Patch Changes
-
#10891
ab42a5c08Thanks @laverdet! - Fixes a bug in how multipart responses are read when using@defer. When reading a multipart body,HttpLinkno longer attempts to parse the boundary (e.g."---"or other boundary string) within the response data itself, only when reading the beginning of each mulitpart chunked message. -
#10789
23a4e1578Thanks @phryneas! - Fix a bug where other fields could be aliased to__typenameorid, in which case an incoming result would be merged into the wrong cache entry.
New Contributors
- @AngadSethi made their first contribution in https://github.com/apollographql/apollo-client/pull/10837
- @laverdet made their first contribution in https://github.com/apollographql/apollo-client/pull/10891
- @beerose made their first contribution in https://github.com/apollographql/apollo-client/pull/10910
Additional notes2 sources agree
Open source →Patch Changes
-
#10891
ab42a5c08Thanks @laverdet! - Fixes a bug in how multipart responses are read when using@defer. When reading a multipart body,HttpLinkno longer attempts to parse the boundary (e.g."---"or other boundary string) within the response data itself, only when reading the beginning of each mulitpart chunked message. -
#10789
23a4e1578Thanks @phryneas! - Fix a bug where other fields could be aliased to__typenameorid, in which case an incoming result would be merged into the wrong cache entry.
-
- 3.7.143 May 2023
Release notes
Open source →Patch Changes
-
#10764
1b0a61fe5Thanks @phryneas! - DeprecateuseFragmentreturnPartialDataoption -
#10810
a6252774fThanks @dleavitt! - Fix type signature ofServerError.In <3.7
HttpLinkandBatchHttpLinkwould return aServerError.messageof e.g."Unexpected token 'E', \"Error! Foo bar\" is not valid JSON"and aServerError.resultofundefinedin the case where a server returned a >= 300 response code with a response body containing a string that could not be parsed as JSON.In >=3.7,
messagebecame e.g.Response not successful: Received status code 302andresultbecame the string from the response body, however the type inServerError.resultwas not updated to include thestringtype, which is now properly reflected.
Additional notes2 sources agree
Open source →Patch Changes
-
#10764
1b0a61fe5Thanks @phryneas! - DeprecateuseFragmentreturnPartialDataoption -
#10810
a6252774fThanks @dleavitt! - Fix type signature ofServerError.In <3.7
HttpLinkandBatchHttpLinkwould return aServerError.messageof e.g."Unexpected token 'E', \"Error! Foo bar\" is not valid JSON"and aServerError.resultofundefinedin the case where a server returned a >= 300 response code with a response body containing a string that could not be parsed as JSON.In >=3.7,
messagebecame e.g.Response not successful: Received status code 302andresultbecame the string from the response body, however the type inServerError.resultwas not updated to include thestringtype, which is now properly reflected.
-
- 3.7.1327 Apr 2023
Release notes3 sources agree
Open source →Patch Changes
-
#10805
a5503666cThanks @phryneas! - Fix a potential memory leak in SSR scenarios when manypersistedQueryinstances were created over time. -
#10718
577c68bddThanks @Hsifnus! - Delay Concast subscription teardown slightly inuseSubscriptionto prevent unexpected Concast teardown when oneuseSubscriptionhook tears down its in-flight Concast subscription immediately followed by anotheruseSubscriptionhook reusing and subscribing to that same Concast
-
- 3.7.1212 Apr 2023
Release notes3 sources agree
Open source →Patch Changes
- #10735
895bcdcffThanks @alessbell! - If a multipart chunk contains onlyhasNext: false, immediately complete the observable.
- #10735
- 3.7.1131 Mar 2023
Release notes
Open source →Patch Changes
-
#10586
4175af594Thanks @alessbell! - Improve WebSocket error handling for genericEventreceived on error. For more information see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/error_event. -
#10411
152baac34Thanks @lovasoa! - Simplify error message generation and make 'undefined' an impossible message string. -
#10592
cdb98ae08Thanks @alessbell! - Adds support for multipart subscriptions inHttpLink. -
#10698
38508a251Thanks @jerelmiller! - Changes the behavior ofuseLazyQueryintroduced in #10427 where unmounting a component before a query was resolved would reject the promise with an abort error. Instead, the promise will now resolve naturally with the result from the request.Other notable fixes:
- Kicking off multiple requests in parallel with the execution function will now ensure each returned promise is resolved with the data from its request. Previously, each promise was resolved with data from the last execution.
- Re-rendering
useLazyQuerywith a different query document will now ensure the execution function uses the updated query document. Previously, only the query document rendered the first time would be used for the request.
-
#10660
364bee98fThanks @alessbell! - Upgrades TypeScript to v5. This change is fully backward-compatible and transparent to users. -
#10597
8fb9d190dThanks @phryneas! - Fix a bug where an incoming cache update could prevent future updates from the active link. -
#10629
02605bb3cThanks @phryneas! -useQuery: delay unsubscribe to fix race conditions
Additional notes2 sources agree
Open source →Patch Changes
-
#10586
4175af594Thanks @alessbell! - Improve WebSocket error handling for genericEventreceived on error. For more information see https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/error_event. -
#10411
152baac34Thanks @lovasoa! - Simplify error message generation and make 'undefined' an impossible message string. -
#10592
cdb98ae08Thanks @alessbell! - Adds support for multipart subscriptions inHttpLink. -
#10698
38508a251Thanks @jerelmiller! - Changes the behavior ofuseLazyQueryintroduced in #10427 where unmounting a component before a query was resolved would reject the promise with an abort error. Instead, the promise will now resolve naturally with the result from the request.Other notable fixes:
- Kicking off multiple requests in parallel with the execution function will now ensure each returned promise is resolved with the data from its request. Previously, each promise was resolved with data from the last execution.
- Re-rendering
useLazyQuerywith a different query document will now ensure the execution function uses the updated query document. Previously, only the query document rendered the first time would be used for the request.
-
#10660
364bee98fThanks @alessbell! - Upgrades TypeScript to v5. This change is fully backward-compatible and transparent to users. -
#10597
8fb9d190dThanks @phryneas! - Fix a bug where an incoming cache update could prevent future updates from the active link. -
#10629
02605bb3cThanks @phryneas! -useQuery: delay unsubscribe to fix race conditions
-