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.13.64 Apr 2025
- 3.13.520 Mar 2025
Release notes3 sources agree
Open source →Patch Changes
- #12461
12c8d06Thanks @jerelmiller! - Fix an issue where acache-firstquery would return the result for previous variables when a cache update is issued after simultaneously changing variables and skipping the query.
- #12461
- 3.13.410 Mar 2025
Release notes3 sources agree
Open source →Patch Changes
- #12420
fee9368Thanks @jorenbroekema! - Use import star fromrehacktto prevent issues with importing named exports from external CJS modules.
- #12420
- 3.13.37 Mar 2025
Release notes3 sources agree
Open source →Patch Changes
-
#12362
f6d387cThanks @jerelmiller! - Fixes an issue where callingobservableQuery.getCurrentResult()when theerrorPolicywas set toallwould return thenetworkStatusasNetworkStatus.readywhen there were errors returned in the result. This has been corrected to reportNetworkStatus.error.This bug also affected the
useQueryanduseLazyQueryhooks and may affect you if you check fornetworkStatusin your component.
-
- 3.13.26 Mar 2025
Release notes3 sources agree
Open source →Patch Changes
-
#12409
6aa2f3eThanks @phryneas! - To mitigate problems when Apollo Client ends up more than once in the bundle, some unique symbols were converted intoSymbol.forcalls. -
#12392
644bb26Thanks @Joja81! - Fixes an issue where the DeepOmit type would turn optional properties into required properties. This should only affect you if you were using the omitDeep or stripTypename utilities exported by Apollo Client. -
#12404
4332b88Thanks @jerelmiller! - ShowNaNrather than converting tonullin debug messages fromMockLinkfor unmatchedvariablesvalues.
-
- 3.13.114 Feb 2025
- 3.13.013 Feb 2025
Release notes
Open source →Apollo Client v3.13.0 introduces a new hook,
useSuspenseFragment, as a drop-in replacement foruseFragmentin apps that are using React Suspense. This is the “last” React hook we are introducing in 3.x - we think this rounds out the “big concepts” in our React Suspense and GraphQL fragment story. See the docs for information on this and our other Suspense-supporting hooks. There are some TypeScript quality-of-life improvements shipped in this release forobservableQuery.updateQueryandsubscribeToMore. Additionally, the return type ofupdateQuerynow includesundefinedto allow an early exit from updates. This was always supported at runtime, but was missed on the TypeScript side. On the runtime side, we’ve fixed query deduplication behavior for multipart responses and corrected the error handling inuseMutationcallbacks.onCompletedandonErrorinuseQueryanduseLazyQueryhave been deprecated for multiple reasons. See below for full details 👀Minor Changes
-
#12066
c01da5dThanks @jerelmiller! - Adds a newuseSuspenseFragmenthook.useSuspenseFragmentsuspends untildatais complete. It is a drop-in replacement foruseFragmentwhen you prefer to use Suspense to control the loading state of a fragment. See the documentation for more details. -
#12174
ba5cc33Thanks @jerelmiller! - Ensure errors thrown in theonCompletedcallback fromuseMutationdon't callonError. -
#12340
716d02eThanks @phryneas! - Deprecate theonCompletedandonErrorcallbacks ofuseQueryanduseLazyQuery. For more context, please see the related issue on GitHub. -
#12276
670f112Thanks @Cellule! - Provide a more type-safe option for the previous data value passed toobservableQuery.updateQuery. Using it could result in crashes at runtime as this callback could be called with partial data even though its type reported the value as a complete result.The
updateQuerycallback function is now called with a new type-safepreviousDataproperty and a newcompleteproperty in the 2nd argument that determines whetherpreviousDatais a complete or partial result.As a result of this change, it is recommended to use the
previousDataproperty passed to the 2nd argument of the callback rather than using the previous data value from the first argument since that value is not type-safe. The first argument is now deprecated and will be removed in a future version of Apollo Client.observableQuery.updateQuery( (unsafePreviousData, { previousData, complete }) => { previousData; // ^? TData | DeepPartial<TData> | undefined if (complete) { previousData; // ^? TData } else { previousData; // ^? DeepPartial<TData> | undefined } } ); -
#12174
ba5cc33Thanks @jerelmiller! - Reject the mutation promise if errors are thrown in theonCompletedcallback ofuseMutation.
Patch Changes
-
#12276
670f112Thanks @Cellule! - Fix the return type of theupdateQueryfunction to allow forundefined.updateQueryhad the ability to bail out of the update by returning a falsey value, but the return type enforced a query value.observableQuery.updateQuery( (unsafePreviousData, { previousData, complete }) => { if (!complete) { // Bail out of the update by returning early return; } // ... } ); -
#12296
2422df2Thanks @Cellule! - Deprecate optionignoreResultsinuseMutation. Once this option is removed, existing code still using it might see increase in re-renders. If you don't want to synchronize your component state with the mutation, please useuseApolloClientto get your ApolloClient instance and callclient.mutatedirectly. -
#12338
67c16c9Thanks @phryneas! - In case of a multipart response (e.g. with@defer), query deduplication will now keep going until the final chunk has been received. -
#12276
670f112Thanks @Cellule! - Fix the type of thevariablesproperty passed as the 2nd argument to thesubscribeToMorecallback. This was previously reported as thevariablestype for the subscription itself, but is now properly typed as the queryvariables.
Additional notes2 sources agree
Open source →Minor Changes
-
#12066
c01da5dThanks @jerelmiller! - Adds a newuseSuspenseFragmenthook.useSuspenseFragmentsuspends untildatais complete. It is a drop-in replacement foruseFragmentwhen you prefer to use Suspense to control the loading state of a fragment. See the documentation for more details. -
#12174
ba5cc33Thanks @jerelmiller! - Ensure errors thrown in theonCompletedcallback fromuseMutationdon't callonError. -
#12340
716d02eThanks @phryneas! - Deprecate theonCompletedandonErrorcallbacks ofuseQueryanduseLazyQuery. For more context, please see the related issue on GitHub. -
#12276
670f112Thanks @Cellule! - Provide a more type-safe option for the previous data value passed toobservableQuery.updateQuery. Using it could result in crashes at runtime as this callback could be called with partial data even though its type reported the value as a complete result.The
updateQuerycallback function is now called with a new type-safepreviousDataproperty and a newcompleteproperty in the 2nd argument that determines whetherpreviousDatais a complete or partial result.As a result of this change, it is recommended to use the
previousDataproperty passed to the 2nd argument of the callback rather than using the previous data value from the first argument since that value is not type-safe. The first argument is now deprecated and will be removed in a future version of Apollo Client.observableQuery.updateQuery( (unsafePreviousData, { previousData, complete }) => { previousData; // ^? TData | DeepPartial<TData> | undefined if (complete) { previousData; // ^? TData } else { previousData; // ^? DeepPartial<TData> | undefined } } ); -
#12174
ba5cc33Thanks @jerelmiller! - Reject the mutation promise if errors are thrown in theonCompletedcallback ofuseMutation.
Patch Changes
-
#12276
670f112Thanks @Cellule! - Fix the return type of theupdateQueryfunction to allow forundefined.updateQueryhad the ability to bail out of the update by returning a falsey value, but the return type enforced a query value.observableQuery.updateQuery( (unsafePreviousData, { previousData, complete }) => { if (!complete) { // Bail out of the update by returning early return; } // ... } ); -
#12296
2422df2Thanks @Cellule! - Deprecate optionignoreResultsinuseMutation. Once this option is removed, existing code still using it might see increase in re-renders. If you don't want to synchronize your component state with the mutation, please useuseApolloClientto get your ApolloClient instance and callclient.mutatedirectly. -
#12338
67c16c9Thanks @phryneas! - In case of a multipart response (e.g. with@defer), query deduplication will now keep going until the final chunk has been received. -
#12276
670f112Thanks @Cellule! - Fix the type of thevariablesproperty passed as the 2nd argument to thesubscribeToMorecallback. This was previously reported as thevariablestype for the subscription itself, but is now properly typed as the queryvariables.
-
- 3.13.0-rc.07 Feb 2025pre-release
Release notes3 sources agree
Open source →Minor Changes
-
#12066
c01da5dThanks @jerelmiller! - Adds a newuseSuspenseFragmenthook.useSuspenseFragmentsuspends untildatais complete. It is a drop-in replacement foruseFragmentwhen you prefer to use Suspense to control the loading state of a fragment. -
#12174
ba5cc33Thanks @jerelmiller! - Ensure errors thrown in theonCompletedcallback fromuseMutationdon't callonError. -
#12340
716d02eThanks @phryneas! - Deprecate theonCompletedandonErrorcallbacks ofuseQueryanduseLazyQuery. For more context, please see the related issue on GitHub. -
#12276
670f112Thanks @Cellule! - Provide a more type-safe option for the previous data value passed toobservableQuery.updateQuery. Using it could result in crashes at runtime as this callback could be called with partial data even though its type reported the value as a complete result.The
updateQuerycallback function is now called with a new type-safepreviousDataproperty and a newcompleteproperty in the 2nd argument that determines whetherpreviousDatais a complete or partial result.As a result of this change, it is recommended to use the
previousDataproperty passed to the 2nd argument of the callback rather than using the previous data value from the first argument since that value is not type-safe. The first argument is now deprecated and will be removed in a future version of Apollo Client.observableQuery.updateQuery( (unsafePreviousData, { previousData, complete }) => { previousData; // ^? TData | DeepPartial<TData> | undefined if (complete) { previousData; // ^? TData } else { previousData; // ^? DeepPartial<TData> | undefined } } ); -
#12174
ba5cc33Thanks @jerelmiller! - Reject the mutation promise if errors are thrown in theonCompletedcallback ofuseMutation.
Patch Changes
-
#12276
670f112Thanks @Cellule! - Fix the return type of theupdateQueryfunction to allow forundefined.updateQueryhad the ability to bail out of the update by returning a falsey value, but the return type enforced a query value.observableQuery.updateQuery( (unsafePreviousData, { previousData, complete }) => { if (!complete) { // Bail out of the update by returning early return; } // ... } ); -
#12296
2422df2Thanks @Cellule! - Deprecate optionignoreResultsinuseMutation. Once this option is removed, existing code still using it might see increase in re-renders. If you don't want to synchronize your component state with the mutation, please useuseApolloClientto get your ApolloClient instance and callclient.mutatedirectly. -
#12338
67c16c9Thanks @phryneas! - In case of a multipart response (e.g. with@defer), query deduplication will now keep going until the final chunk has been received. -
#12276
670f112Thanks @Cellule! - Fix the type of thevariablesproperty passed as the 2nd argument to thesubscribeToMoreupdateQuerycallback. This was previously reported as thevariablestype for the subscription itself, but is now properly typed as the queryvariables.
-
- 3.12.117 Feb 2025
Release notes3 sources agree
Open source →Patch Changes
-
#12351
3da908bThanks @jerelmiller! - Fixes an issue where the wrongnetworkStatusandloadingvalue was emitted fromobservableQuerywhen callingfetchMorewith ano-cachefetch policy. ThenetworkStatusnow properly reports asreadyandloadingasfalseafter the result is returned. -
#12354
a24ef94Thanks @phryneas! - Fix missingmain.d.ctsfile
-
- 3.12.106 Feb 2025
- 3.12.93 Feb 2025
Release notes3 sources agree
Open source →Patch Changes
-
#12321
daa4f33Thanks @jerelmiller! - Fix type ofextensionsinprotocolErrorsforApolloErrorand theonErrorlink. According to the multipart HTTP subscription protocol, fatal tranport errors follow the GraphQL error format which requireextensionsto be a map as its value instead of an array. -
#12318
b17968bThanks @jerelmiller! - AllowRetryLinkto retry an operation when fatal transport-level errors are emitted from multipart subscriptions.const retryLink = new RetryLink({ attempts: (count, operation, error) => { if (error instanceof ApolloError) { // errors available on the `protocolErrors` field in `ApolloError` console.log(error.protocolErrors); } return true; }, });
-
- 3.12.827 Jan 2025
- 3.12.722 Jan 2025
Release notes3 sources agree
Open source →Patch Changes
-
#12281
d638ec3Thanks @jerelmiller! - Make fatal tranport-level errors from multipart subscriptions available to the error link with theprotocolErrorsproperty.const errorLink = onError(({ protocolErrors }) => { if (protocolErrors) { console.log(protocolErrors); } }); -
#12281
d638ec3Thanks @jerelmiller! - Fix the array type for theerrorsfield on theApolloPayloadResulttype. This type was always in the shape of the GraphQL error format, per the multipart subscriptions protocol and never a plain string or a JavaScript error object.
-
- 3.12.614 Jan 2025
Release notes3 sources agree
Open source →Patch Changes
-
#12267
d57429dThanks @jerelmiller! - Maintain theTDatatype when used withUnmaskedwhenTDatais not a masked type generated from GraphQL Codegen. -
#12270
3601246Thanks @jerelmiller! - Fix handling of tagged/branded primitive types when used as scalar values withUnmasked.
-
- 3.12.59 Jan 2025
Release notes
Open source →Patch Changes
-
#12252
cb9cd4eThanks @jerelmiller! - Changes the default behavior of theMaybeMaskedtype to preserve types unless otherwise specified. This change makes it easier to upgrade from older versions of the client where types could have unexpectedly changed in the application due to the default of trying to unwrap types into unmasked types. This change also fixes the compilation performance regression experienced when simply upgrading the client since types are now preserved by default.A new
modeoption has now been introduced to allow for the old behavior. See the next section on migrating if you wish to maintain the old default behavior after upgrading to this version.Migrating from <= v3.12.4
If you've adopted data masking and have opted in to using masked types by setting the
enabledproperty totrue, you can remove this configuration entirely:-declare module "@apollo/client" { - interface DataMasking { - mode: "unmask" - } -}If you prefer to specify the behavior explicitly, change the property from
enabled: true, tomode: "preserveTypes":declare module "@apollo/client" { interface DataMasking { - enabled: true + mode: "preserveTypes" } }If you rely on the default behavior in 3.12.4 or below and would like to continue to use unmasked types by default, set the
modetounmask:declare module "@apollo/client" { interface DataMasking { mode: "unmask"; } }
Additional notes2 sources agree
Open source →Patch Changes
-
#12252
cb9cd4eThanks @jerelmiller! - Changes the default behavior of theMaybeMaskedtype to preserve types unless otherwise specified. This change makes it easier to upgrade from older versions of the client where types could have unexpectedly changed in the application due to the default of trying to unwrap types into unmasked types. This change also fixes the compilation performance regression experienced when simply upgrading the client since types are now preserved by default.A new
modeoption has now been introduced to allow for the old behavior. See the next section on migrating if you wish to maintain the old default behavior after upgrading to this version.Migrating from <= v3.12.4
If you've adopted data masking and have opted in to using masked types by setting the
enabledproperty totrue, you can remove this configuration entirely:-declare module "@apollo/client" { - interface DataMasking { - mode: "unmask" - } -}If you prefer to specify the behavior explicitly, change the property from
enabled: true, tomode: "preserveTypes":declare module "@apollo/client" { interface DataMasking { - enabled: true + mode: "preserveTypes" } }If you rely on the default behavior in 3.12.4 or below and would like to continue to use unmasked types by default, set the
modetounmask:declare module "@apollo/client" { interface DataMasking { mode: "unmask"; } }
-
- 3.12.419 Dec 2024
- 3.12.312 Dec 2024
Release notes3 sources agree
Open source →Patch Changes
-
#12214
8bfee88Thanks @phryneas! - Data masking: prevent infinite recursion ofContainsFragmentsRefstype -
#12204
851deb0Thanks @jerelmiller! - FixUnmaskedunwrapping tuple types into an array of their subtypes. -
#12204
851deb0Thanks @jerelmiller! - EnsureMaybeMaskeddoes not try and unwrap types that contain index signatures. -
#12204
851deb0Thanks @jerelmiller! - EnsureMaybeMaskeddoes not try to unwrap the type asUnmaskedif the type containsany.
-
- 3.12.25 Dec 2024
Release notes3 sources agree
Open source →Patch Changes
- #12175
84af347Thanks @jerelmiller! - Update peer deps to allow for React 19 stable release.
- #12175
- 3.12.15 Dec 2024
Release notes3 sources agree
Open source → - 3.12.04 Dec 2024
Release notes3 sources agree
Open source →Minor Changes
Data masking 🎭
-
#12042
1c0ecbfThanks @jerelmiller! - Introduces data masking in Apollo Client.Data masking enforces that only the fields requested by the query or fragment is available to that component. Data masking is best paired with colocated fragments.
To enable data masking in Apollo Client, set the
dataMaskingoption totrue.new ApolloClient({ dataMasking: true, // ... other options });For detailed information on data masking, including how to incrementally adopt it in an existing applications, see the data masking documentation.
-
#12131
21c3f08Thanks @jerelmiller! - Allownullas a validfromvalue inuseFragment.
<details open> <summary><h3>More Patch Changes</h3></summary>
-
#12126
d10d702Thanks @jerelmiller! - Maintain the existing document if its unchanged by the codemod and move to more naive whitespace formatting -
#12150
9ed1e1eThanks @jerelmiller! - Fix issue when usingUnmaskedwith older versions of TypeScript when used with array fields. -
#12116
8ae6e4eThanks @jerelmiller! - Prevent field accessor warnings when using@unmask(mode: "migrate")on objects that are passed intocache.identify. -
#12120
6a98e76Thanks @jerelmiller! - Provide a codemod that applies@unmaskto all named fragments for all operations and fragments.Learn how to use the codemod in the incremental adoption documentation.
-
#12134
cfaf4efThanks @jerelmiller! - Fix issue where data went missing when an unmasked fragment in migrate mode selected fields that the parent did not. -
#12154
d933defThanks @phryneas! - Data masking types: handle overlapping nested array types and fragments on interface types. -
#12139
5a53e15Thanks @phryneas! - Fix issue where masked data would sometimes get returned when the field was part of a child fragment from a fragment unmasked by the parent query. -
#12123
8422a30Thanks @jerelmiller! - Warn when using data masking with "no-cache" operations. -
#12139
5a53e15Thanks @phryneas! - Fix issue where the warning emitted by@unmask(mode: "migrate")would trigger unnecessarily when the fragment was used alongside a masked fragment inside an inline fragment. -
#12114
1d4ce00Thanks @jerelmiller! - Fix error when combining@unmaskand@deferdirectives on a fragment spread when data masking is enabled. -
#12130
1e7d009Thanks @jerelmiller! - Fix error thrown when applying unmask migrate mode warnings on interface types with selection sets that contain inline fragment conditions. -
#12152
78137ecThanks @phryneas! - Add a helper that will skip the TS unmasking alorithm when no fragments are present on type level -
#12126
d10d702Thanks @jerelmiller! - Ensure documents unchanged by the codemod are left untouched. -
#12133
a6ece37Thanks @jerelmiller! - Ensurenullis retained in nullable types when unmasking a type with theUnmaskedhelper type. -
#12139
5a53e15Thanks @phryneas! - Fix issue that threw errors when masking partial data with@unmask(mode: "migrate").
</details>
-
- 3.12.0-rc.427 Nov 2024pre-release
- 3.12.0-rc.320 Nov 2024pre-release
- 3.12.0-rc.219 Nov 2024pre-release
Release notes3 sources agree
Open source →Patch Changes
-
#12139
5a53e15Thanks @phryneas! - Fix issue where masked data would sometimes get returned when the field was part of a child fragment from a fragment unmasked by the parent query. -
#12139
5a53e15Thanks @phryneas! - Fix issue where the warning emitted by@unmask(mode: "migrate")would trigger unnecessarily when the fragment was used alongside a masked fragment inside an inline fragment. -
#12139
5a53e15Thanks @phryneas! - Fix issue that threw errors when masking partial data with@unmask(mode: "migrate").
-
- 3.12.0-rc.115 Nov 2024pre-release
Release notes3 sources agree
Open source →Minor Changes
- #12131
21c3f08Thanks @jerelmiller! - Allownullas a validfromvalue inuseFragment.
Patch Changes
-
#12126
d10d702Thanks @jerelmiller! - Maintain the existing document if its unchanged by the codemod and move to more naive whitespace formatting -
#12134
cfaf4efThanks @jerelmiller! - Fix issue where data went missing when an unmasked fragment in migrate mode selected fields that the parent did not. -
#12130
1e7d009Thanks @jerelmiller! - Fix error thrown when applying unmask migrate mode warnings on interface types with selection sets that contain inline fragment conditions. -
#12126
d10d702Thanks @jerelmiller! - Ensure documents unchanged by the codemod are left untouched. -
#12133
a6ece37Thanks @jerelmiller! - Ensurenullis retained in nullable types when unmasking a type with theUnmaskedhelper type.
- #12131
- 3.12.0-rc.013 Nov 2024pre-release
Release notes
Open source →Patch Changes
-
#12116
8ae6e4eThanks @jerelmiller! - Prevent field accessor warnings when using@unmask(mode: "migrate")on objects that are passed intocache.identify. -
#12120
6a98e76Thanks @jerelmiller! - Provide a codemod that applies@unmaskto all named fragments for all operations and fragments. To use the codemod, run the following command:npx jscodeshift -t node_modules/@apollo/client/scripts/codemods/data-masking/unmask.ts --extensions tsx --parser tsx path/to/app/To customize the tag used to search for GraphQL operations, use the
--tagoption. By default the codemod looks forgqlandgraphqltags.To apply the directive in migrate mode in order to receive runtime warnings on potentially masked fields, use the
--mode migrateoption.For more information on the options that can be used with
jscodeshift, check out thejscodeshiftdocumentation. -
#12121
1085a95Thanks @jerelmiller! - Warn when using data masking with "no-cache" operations. -
#12114
1d4ce00Thanks @jerelmiller! - Fix error when combining@unmaskand@deferdirectives on a fragment spread when data masking is enabled.
Additional notes2 sources agree
Open source →Patch Changes
-
#12116
8ae6e4eThanks @jerelmiller! - Prevent field accessor warnings when using@unmask(mode: "migrate")on objects that are passed intocache.identify. -
#12120
6a98e76Thanks @jerelmiller! - Provide a codemod that applies@unmaskto all named fragments for all operations and fragments. To use the codemod, run the following command:npx jscodeshift -t node_modules/@apollo/client/scripts/codemods/data-masking/unmask.ts --extensions tsx --parser tsx path/to/app/To customize the tag used to search for GraphQL operations, use the
--tagoption. By default the codemod looks forgqlandgraphqltags.To apply the directive in migrate mode in order to receive runtime warnings on potentially masked fields, use the
--mode migrateoption.For more information on the options that can be used with
jscodeshift, check out thejscodeshiftdocumentation. -
#12121
1085a95Thanks @jerelmiller! - Warn when using data masking with "no-cache" operations. -
#12114
1d4ce00Thanks @jerelmiller! - Fix error when combining@unmaskand@deferdirectives on a fragment spread when data masking is enabled.
-
- 3.12.0-alpha.01 Oct 2024pre-release
Release notes3 sources agree
Open source →Minor Changes
-
#12042
1c0ecbfThanks @jerelmiller! - Introduces data masking into Apollo Client. Data masking allows components to access only the data they asked for through GraphQL fragments. This prevents coupling between components that might otherwise implicitly rely on fields not requested by the component. Data masking also provides the benefit that masked fields only rerender components that ask for the field.To enable data masking in Apollo Client, set the
dataMaskingoption totrue.new ApolloClient({ dataMasking: true, // ... other options });You can selectively disable data masking using the
@unmaskdirective. Apply this to any named fragment to receive all fields requested by the fragment.query { user { id ...UserFields @unmask } }To help with migration, use the
@unmaskmigrate mode which will add warnings when accessing fields that would otherwise be masked.query { user { id ...UserFields @unmask(mode: "migrate") } }
-
- 3.11.11-rc.013 Nov 2024pre-releasewithdrawn: Please use version 3.12.0-rc.0 instead
Nothing published for this version
- 3.11.1011 Nov 2024
Release notes3 sources agree
Open source →Patch Changes
- #12093
1765668Thanks @mgmolisani! - Fixed a bug when evaluating the devtools flag with the new syntaxdevtools.enabledthat could result totruewhen explicitly set tofalse.
- #12093
- 3.11.97 Nov 2024
Release notes3 sources agree
Open source →Patch Changes
- #12110
a3f95c6Thanks @jerelmiller! - Fix an issue where errors returned from afetchMorecall from a Suspense hook would cause a Suspense boundary to be shown indefinitely.
- #12110
- 3.11.85 Sept 2024
- 3.11.74 Sept 2024
Release notes3 sources agree
Open source →Patch Changes
- #12052
e471cefThanks @jerelmiller! - Fixes a regression from where passing an invalid identifier tofrominuseFragmentwould result in the warningTypeError: Cannot read properties of undefined (reading '__typename').
- #12052
- 3.11.63 Sept 2024
Release notes3 sources agree
Open source →Patch Changes
-
#12049
9c26892Thanks @phryneas and @maciesielka! - Fix a bug whereuseFragmentdid not re-render as expected -
#12044
04462a2Thanks @DoctorJohn! - Cache theuseSubscriptionhook'srestartfunction definition between re-renders.
-
- 3.11.528 Aug 2024
Release notes3 sources agree
Open source →Patch Changes
-
#12027
eb3e21bThanks @JavaScriptBach! - TypeMutationResult.resetas an arrow function -
#12020
82d8cb4Thanks @jerelmiller! - Better conform to Rules of React by avoiding write of ref in render foruseFragment.
-
- 3.11.47 Aug 2024
Release notes3 sources agree
Open source →Patch Changes
-
#11994
41b17e5Thanks @jerelmiller! - Update theModifierfunction type to allowcache.modifyto return deeply partial data. -
#11989
e609156Thanks @phryneas! - Fix a potential crash when callingclearStorewhile a query was running.Previously, calling
client.clearStore()while a query was running had one of these results:useQuerywould stay in aloading: truestate.useLazyQuerywould stay in aloading: truestate, but also crash with a"Cannot read property 'data' of undefined"error.
Now, in both cases, the hook will enter an error state with a
networkError, and the promise returned by theuseLazyQueryexecutefunction will return a result in an error state. -
#11994
41b17e5Thanks @jerelmiller! - Prevent accidental distribution oncache.modifyfield modifiers when a field is a union type array.
-
- 3.11.35 Aug 2024
Release notes3 sources agree
Open source →Patch Changes
-
#11984
5db1659Thanks @jerelmiller! - Fix an issue where multiple fetches with results that returned errors would sometimes set thedataproperty with anerrorPolicyofnone. -
#11974
c95848eThanks @jerelmiller! - Fix an issue wherefetchMorewould write its result data to the cache when using it with ano-cachefetch policy. -
#11974
c95848eThanks @jerelmiller! - Fix an issue where executingfetchMorewith ano-cachefetch policy could sometimes result in multiple network requests. -
#11974
c95848eThanks @jerelmiller! -Potentially disruptive change
When calling
fetchMorewith a query that has ano-cachefetch policy,fetchMorewill now throw if anupdateQueryfunction is not provided. This provides a mechanism to merge the results from thefetchMorecall with the query's previous result.
-
- 3.11.231 Jul 2024
Release notes3 sources agree
Open source →Patch Changes
- #11980
38c0a2cThanks @jerelmiller! - Fix missinggetServerSnapshoterror when usinguseSubscriptionon the server.
- #11980
- 3.11.123 Jul 2024
Release notes3 sources agree
Open source →Patch Changes
-
#11969
061cab6Thanks @jerelmiller! - Remove check forwindow.__APOLLO_CLIENT__when determining whether to connect to Apollo Client Devtools whenconnectToDevtoolsordevtools.enabledis not specified. This now simply checks to see if the application is in development mode. -
#11971
ecf77f6Thanks @jerelmiller! - Prevent thesetTimeoutfor suggesting devtools from running in non-browser environments.
-
- 3.11.022 Jul 2024
Release notes3 sources agree
Open source →Potentially Breaking Fixes
-
#11789
5793301Thanks @phryneas! - Changes usages of theGraphQLErrortype toGraphQLFormattedError.This was a type bug - these errors were never
GraphQLErrorinstances to begin with, and theGraphQLErrorclass has additional properties that can never be correctly rehydrated from a GraphQL result. The correct type to use here isGraphQLFormattedError.Similarly, please ensure to use the type
FormattedExecutionResultinstead ofExecutionResult- the non-"Formatted" versions of these types are for use on the server only, but don't get transported over the network. -
#11626
228429aThanks @phryneas! - CallnextFetchPolicywith "variables-changed" even if there is afetchPolicyspecified.Previously this would only be called when the current
fetchPolicywas equal to thefetchPolicyoption or the option was not specified. If you usenextFetchPolicyas a function, expect to see this function called more often.Due to this bug, this also meant that the
fetchPolicymight be reset to the initialfetchPolicy, even when you specified anextFetchPolicyfunction. If you previously relied on this behavior, you will need to update yournextFetchPolicycallback function to implement this resetting behavior.As an example, if your code looked like the following:
useQuery(QUERY, { nextFetchPolicy(currentFetchPolicy, info) { // your logic here } );Update your function to the following to reimplement the resetting behavior:
useQuery(QUERY, { nextFetchPolicy(currentFetchPolicy, info) { if (info.reason === 'variables-changed') { return info.initialFetchPolicy; } // your logic here } );
Minor Changes
-
#11923
d88c7f8Thanks @jerelmiller! - Add support forsubscribeToMorefunction touseQueryRefHandlers. -
#11854
3812800Thanks @jcostello-atlassian! - Support extensions in useSubscription -
#11923
d88c7f8Thanks @jerelmiller! - Add support forsubscribeToMorefunction touseLoadableQuery. -
#11863
98e44f7Thanks @phryneas! - ReimplementuseSubscriptionto fix rules of React violations. -
#11869
a69327cThanks @phryneas! - Rewrite big parts ofuseQueryanduseLazyQueryto be more compliant with the Rules of React and React Compiler -
#11936
1b23337Thanks @jerelmiller! - Add the ability to specify a name for the client instance for use with Apollo Client Devtools. This is useful when instantiating multiple clients to identify the client instance more easily. This deprecates theconnectToDevtoolsoption in favor of a newdevtoolsconfiguration.new ApolloClient({ devtools: { enabled: true, name: "Test Client", }, });This option is backwards-compatible with
connectToDevtoolsand will be used in the absense of adevtoolsoption. -
#11923
d88c7f8Thanks @jerelmiller! - Add support forsubscribeToMorefunction touseBackgroundQuery. -
#11930
a768575Thanks @jerelmiller! - Deprecates experimental schema testing utilities introduced in 3.10 in favor of recommending@apollo/graphql-testing-library.
Patch Changes
-
#11951
0de03afThanks @phryneas! - add React 19 RC topeerDependencies -
#11927
2941824Thanks @phryneas! - Addrestartfunction touseSubscription. -
#11949
4528918Thanks @alessbell! - Remove deprecatedwatchFragmentoption,canonizeResults -
#11937
78332beThanks @phryneas! -createSchemaFetch: simulate serialized errors instead of anApolloErrorinstance -
#11902
96422ceThanks @phryneas! - Addcausefield toApolloError. -
#11806
8df6013Thanks @phryneas! - MockLink: add query default variables if not specified in mock request -
#11926
3dd6432Thanks @phryneas! -watchFragment: forward additional options todiffOptions -
#11946
7d833b8Thanks @jerelmiller! - Fix issue where mutations were not accessible by Apollo Client Devtools in 3.11.0-rc.0. -
#11944
8f3d7ebThanks @sneyderdev! - AllowIgnoreModifierto be returned from aoptimisticResponsefunction when inferring from aTypedDocumentNodewhen used with a generic argument. -
#11954
4a6e86aThanks @phryneas! - Document (and deprecate) the previously undocumentederrorsproperty on theuseQueryQueryResulttype. -
#11719
09a6677Thanks @phryneas! - Allow wrappingcreateQueryPreloader -
#11921
70406bfThanks @phryneas! - addignoreResultsoption touseSubscription
-
- 3.11.0-rc.215 Jul 2024pre-release
Release notes3 sources agree
Open source →Patch Changes
-
#11951
0de03afThanks @phryneas! - add React 19 RC topeerDependencies -
#11937
78332beThanks @phryneas! -createSchemaFetch: simulate serialized errors instead of anApolloErrorinstance -
#11944
8f3d7ebThanks @sneyderdev! - AllowIgnoreModifierto be returned from aoptimisticResponsefunction when inferring from aTypedDocumentNodewhen used with a generic argument. -
#11954
4a6e86aThanks @phryneas! - Document (and deprecate) the previously undocumentederrorsproperty on theuseQueryQueryResulttype.
-
- 3.11.0-rc.110 Jul 2024pre-release
Release notes3 sources agree
Open source →Patch Changes
-
#11949
4528918Thanks @alessbell! - Remove deprecatedwatchFragmentoption,canonizeResults -
#11926
3dd6432Thanks @phryneas! -watchFragment: forward additional options todiffOptions -
#11946
7d833b8Thanks @jerelmiller! - Fix issue where mutations were not accessible by Apollo Client Devtools in 3.11.0-rc.0.
-
- 3.11.0-rc.09 Jul 2024pre-release
Release notes3 sources agree
Open source →Minor Changes
-
#11923
d88c7f8Thanks @jerelmiller! - Add support forsubscribeToMorefunction touseQueryRefHandlers. -
#11854
3812800Thanks @jcostello-atlassian! - Support extensions in useSubscription -
#11923
d88c7f8Thanks @jerelmiller! - Add support forsubscribeToMorefunction touseLoadableQuery. -
#11863
98e44f7Thanks @phryneas! - ReimplementuseSubscriptionto fix rules of React violations. -
#11869
a69327cThanks @phryneas! - Rewrite big parts ofuseQueryanduseLazyQueryto be more compliant with the Rules of React and React Compiler -
#11936
1b23337Thanks @jerelmiller! - Add the ability to specify a name for the client instance for use with Apollo Client Devtools. This is useful when instantiating multiple clients to identify the client instance more easily. This deprecates theconnectToDevtoolsoption in favor of a newdevtoolsconfiguration.new ApolloClient({ devtools: { enabled: true, name: "Test Client", }, });This option is backwards-compatible with
connectToDevtoolsand will be used in the absense of adevtoolsoption. -
#11923
d88c7f8Thanks @jerelmiller! - Add support forsubscribeToMorefunction touseBackgroundQuery. -
#11789
5793301Thanks @phryneas! - Changes usages of theGraphQLErrortype toGraphQLFormattedError.This was a type bug - these errors were never
GraphQLErrorinstances to begin with, and theGraphQLErrorclass has additional properties that can never be correctly rehydrated from a GraphQL result. The correct type to use here isGraphQLFormattedError.Similarly, please ensure to use the type
FormattedExecutionResultinstead ofExecutionResult- the non-"Formatted" versions of these types are for use on the server only, but don't get transported over the network. -
#11930
a768575Thanks @jerelmiller! - Deprecates experimental schema testing utilities introduced in 3.10 in favor of recommending@apollo/graphql-testing-library.
Patch Changes
-
#11927
2941824Thanks @phryneas! - Addrestartfunction touseSubscription. -
#11902
96422ceThanks @phryneas! - Addcausefield toApolloError. -
#11806
8df6013Thanks @phryneas! - MockLink: add query default variables if not specified in mock request -
#11626
228429aThanks @phryneas! - CallnextFetchPolicywith "variables-changed" even if there is afetchPolicyspecified. (fixes #11365) -
#11719
09a6677Thanks @phryneas! - Allow wrappingcreateQueryPreloader -
#11921
70406bfThanks @phryneas! - addignoreResultsoption touseSubscription
-
- 3.10.827 Jun 2024
Release notes3 sources agree
Open source →Patch Changes
- #11911
1f0460aThanks @jerelmiller! - Allowundefinedto be returned from acache.modifymodifier function when a generic type argument is used.
- #11911
- 3.10.726 Jun 2024
Release notes3 sources agree
Open source →Patch Changes
-
#11901
10a8c0aThanks @phryneas! - updatecanUseLayoutEffectcheck to also allow for layout effects in React Native -
#11861
1aed0e8Thanks @henryqdineen! - Defend against non-serializable params ininvariantWrappers -
#11905
29755daThanks @phryneas! - Add.d.ctsfiles for cjs bundles -
#11906
d104759Thanks @phryneas! - chore: update TypeScript to 5.5
-
- 3.10.621 Jun 2024
- 3.10.512 Jun 2024
Release notes3 sources agree
Open source →Patch Changes
-
#11888
7fb7939Thanks @phryneas! - switchuseRenderGuardto an approach not accessing React's internals -
#11511
6536369Thanks @phryneas! -useLoadableQuery: ensure thatloadQueryis updated if the ApolloClient instance changes -
#11860
8740f19Thanks @alessbell! - Fixes #11849 by reevaluatingwindow.fetcheach timeBatchHttpLinkuses it, if not configured viaoptions.fetch. Takes the same approach as PR #8603 which fixed the same issue inHttpLink. -
#11852
d502a69Thanks @phryneas! - Fix a bug where calling theuseMutationresetfunction would point the hook to an outdatedclientreference. -
#11329
3d164eaThanks @PaLy! - Fix graphQLErrors in Error Link if networkError.result is an empty string -
#11852
d502a69Thanks @phryneas! - Prevent writing to a ref in render inuseMutation. As a result, you might encounter problems in the future if you call the mutation'sexecutefunction during render. Please note that this was never supported behavior, and we strongly recommend against it. -
#11848
ad63924Thanks @phryneas! - Ensure covariant behavior:MockedResponse<X,Y>should be assignable toMockedResponse -
#11851
45c47beThanks @phryneas! - Avoid usage of useRef in useInternalState to prevent ref access in render. -
#11877
634d91aThanks @phryneas! - Add missing name to tuple member (fix TS5084) -
#11851
45c47beThanks @phryneas! - Fix a bug whereuseLazyQuerywould not pick up a client change.
-
- 3.10.415 May 2024
Release notes3 sources agree
Open source →Patch Changes
-
#11838
8475346Thanks @alex-kinokon! - Don’t prompt for DevTools installation for browser extension page -
#11839
6481fe1Thanks @jerelmiller! - Fix a regression in 3.9.5 where a merge function that returned an incomplete result would not allow the client to refetch in order to fulfill the query. -
#11844
86984f2Thanks @jerelmiller! - Honor the@nonreactivedirective when usingcache.watchFragmentor theuseFragmenthook to avoid rerendering when using these directives. -
#11824
47ad806Thanks @phryneas! - Create brandedQueryReftype without exposed properties.This change deprecates
QueryReferencein favor of aQueryReftype that doesn't expose any properties. This change also updatespreloadQueryto return a newPreloadedQueryReftype, which exposes thetoPromisefunction as it does today. This means that query refs produced byuseBackgroundQueryanduseLoadableQuerynow returnQueryReftypes that do not have access to atoPromisefunction, which was never meant to be used in combination with these hooks.While we tend to avoid any types of breaking changes in patch releases as this, this change was necessary to support an upcoming version of the React Server Component integration, which needed to omit the
toPromisefunction that would otherwise have broken at runtime. Note that this is a TypeScript-only change. At runtime,toPromiseis still present on all queryRefs currently created by this package - but we strongly want to discourage you from accessing it in all cases except for thePreloadedQueryRefuse case.Migration is as simple as replacing all references to
QueryReferencewithQueryRef, so it should be possible to do this with a search & replace in most code bases:-import { QueryReference } from '@apollo/client' +import { QueryRef } from '@apollo/client' - function Component({ queryRef }: { queryRef: QueryReference<TData> }) { + function Component({ queryRef }: { queryRef: QueryRef<TData> }) { // ... } -
#11845
4c5c820Thanks @jerelmiller! - Remove@nonreactivedirectives from queries passed toMockLinkto ensure they are properly matched. -
#11837
dff15b1Thanks @jerelmiller! - Fix an issue where a polled query created in React strict mode may not stop polling after the component unmounts while using thecache-and-networkfetch policy.
-
- 3.10.37 May 2024
- 3.10.23 May 2024
Release notes3 sources agree
Open source →Patch Changes
-
#11821
2675d3cThanks @jerelmiller! - Fix a regression where rerendering a component withuseBackgroundQuerywould recreate thequeryRefinstance when used with React's strict mode. -
#11821
2675d3cThanks @jerelmiller! - Revert the change introduced in 3.9.10 via #11738 that disposed of queryRefs synchronously. This change caused too many issues with strict mode.
-
- 3.10.124 Apr 2024
Release notes3 sources agree
Open source →Patch Changes
-
#11792
5876c35Thanks @phryneas! - AutoCleanedCache: only schedule batched cache cleanup if the cache is full (fixes #11790) -
#11799
1aca7edThanks @phryneas! -RenderPromises: usecanonicalStringifyto serializevariablesto ensure query deduplication is properly applied even whenvariablesare specified in a different order. -
#11803
bf9dd17Thanks @phryneas! - Update therehacktdependency to^0.1.0 -
#11756
60592e9Thanks @henryqdineen! - Fix operation.setContext() type
-
- 3.10.024 Apr 2024
Release notes3 sources agree
Open source →Minor Changes
-
#11605
e2dd4c9Thanks @alessbell! - AddscreateMockFetchutility for integration testing that includes the link chain -
#11760
acd1982Thanks @alessbell! -createTestSchemanow uses graphql-toolsmergeResolversto merge resolvers instead of a shallow merge. -
#11764
f046aa9Thanks @alessbell! - RenamecreateProxiedSchematocreateTestSchemaandcreateMockFetchtocreateSchemaFetch. -
#11777
5dfc79fThanks @alessbell! - CallcreateMockSchemainsidecreateTestSchema. -
#11774
2583488Thanks @alessbell! - Add ability to set min and max delay increateSchemaFetch -
#11605
e2dd4c9Thanks @alessbell! - Adds proxiedSchema and createMockSchema testing utilities -
#11465
7623da7Thanks @alessbell! - AddwatchFragmentmethod to the cache and expose it on ApolloClient, refactoruseFragmentusingwatchFragment. -
#11743
78891f9Thanks @jerelmiller! - Remove alpha designation forqueryRef.toPromise()to stabilize the API. -
#11743
78891f9Thanks @jerelmiller! - Remove alpha designation forcreateQueryPreloaderto stabilize the API. -
#11783
440563aThanks @alessbell! - Moves new testing utilities to their own entrypoint,testing/experimental
Patch Changes
-
#11757
9825295Thanks @phryneas! - AdjustuseReadQuerywrapper logic to work with transported objects. -
#11771
e72cbbaThanks @phryneas! - WrapuseQueryRefHandlersinwrapHook. -
#11754
80d2ba5Thanks @alessbell! - ExportWatchFragmentOptionsandWatchFragmentResultfrom main entrypoint and fix bug wherethiswasn't bound to thewatchFragmentmethod onApolloClient.
-
- 3.10.0-rc.115 Apr 2024pre-release
Release notes3 sources agree
Open source →Minor Changes
-
#11760
acd1982Thanks @alessbell! -createTestSchemanow uses graphql-toolsmergeResolversto merge resolvers instead of a shallow merge. -
#11764
f046aa9Thanks @alessbell! - RenamecreateProxiedSchematocreateTestSchemaandcreateMockFetchtocreateSchemaFetch. -
#11777
5dfc79fThanks @alessbell! - CallcreateMockSchemainsidecreateTestSchema. -
#11774
2583488Thanks @alessbell! - Add ability to set min and max delay increateSchemaFetch -
#11783
440563aThanks @alessbell! - Moves new testing utilities to their own entrypoint,testing/experimental
Patch Changes
-
#11757
9825295Thanks @phryneas! - AdjustuseReadQuerywrapper logic to work with transported objects. -
#11771
e72cbbaThanks @phryneas! - WrapuseQueryRefHandlersinwrapHook. -
#11754
80d2ba5Thanks @alessbell! - ExportWatchFragmentOptionsandWatchFragmentResultfrom main entrypoint and fix bug wherethiswasn't bound to thewatchFragmentmethod onApolloClient.
-
- 3.10.0-rc.02 Apr 2024pre-release
Release notes3 sources agree
Open source →Minor Changes
-
#11605
e2dd4c9Thanks @alessbell! - AddscreateMockFetchutility for integration testing that includes the link chain -
#11605
e2dd4c9Thanks @alessbell! - Adds proxiedSchema and createMockSchema testing utilities -
#11743
78891f9Thanks @jerelmiller! - Remove alpha designation forqueryRef.toPromise()to stabilize the API. -
#11743
78891f9Thanks @jerelmiller! - Remove alpha designation forcreateQueryPreloaderto stabilize the API.
-
- 3.10.0-alpha.118 Mar 2024pre-release
Release notes
Open source →Patch Changes
- #11465
7623da7Thanks @alessbell! - AddwatchFragmentmethod to the cache and expose it on ApolloClient, refactoruseFragmentusingwatchFragment.
- #11465
- 3.9.1110 Apr 2024
Release notes3 sources agree
Open source →Patch Changes
- #11769
04132afThanks @jerelmiller! - Fix an issue where usingskipTokenor theskipoption withuseSuspenseQueryin React's strict mode would perform a network request.
- #11769
- 3.9.101 Apr 2024
Release notes3 sources agree
Open source →Patch Changes
-
#11738
b1a5eb8Thanks @jerelmiller! - Fix an issue where rerenderinguseBackgroundQueryafter thequeryRefhad been disposed, either via the auto dispose timeout or by unmountinguseReadQuery, would cause thequeryRefto be recreated potentially resulting in another network request. -
#11738
b1a5eb8Thanks @jerelmiller! - Allow queryRefs to be disposed of synchronously when a suspense hook unmounts. This prevents some situations where using a suspense hook with the same query/variables as the disposed queryRef accidentally used the disposed queryRef rather than creating a new instance. -
#11670
cc5c03bThanks @phryneas! - Bail out ofexecuteSubSelectedArraycalls if the array has 0 elements.
-
- 3.9.922 Mar 2024
- 3.9.820 Mar 2024
Release notes3 sources agree
Open source →Patch Changes
-
#11706
8619bc7Thanks @jerelmiller! - Fix issue in all suspense hooks where returning an empty array after callingfetchMorewould rerender the component with an empty list. -
#11694
835d5f3Thanks @phryneas! - ExposesetErrorMessageHandlerfrom@apollo/client/deventrypoint. -
#11689
cb8ffe5Thanks @jerelmiller! - Fix issue where passing a newfromoption touseFragmentwould first render with the previous value before rerendering with the correct value. -
#11713
642092cThanks @jerelmiller! - Fix issue where setting a defaultwatchQueryoption in theApolloClientconstructor could breakstartTransitionwhen used with suspense hooks.
-
- 3.9.713 Mar 2024
- 3.9.66 Mar 2024
- 3.9.515 Feb 2024
Release notes3 sources agree
Open source →Patch Changes
-
#11595
8c20955Thanks @phryneas! - Bumps the dependencyrehacktto 0.0.5 -
#11592
1133469Thanks @Stephen2! - StrengthenMockedResponse.newDatatype -
#11579
1ba2fd9Thanks @jerelmiller! - Fix issue where partial data is reported touseQuerywhen usingnotifyOnNetworkStatusChangeafter it errors while another overlapping query succeeds. -
#11579
1ba2fd9Thanks @jerelmiller! - Fix an issue where a partial cache write for an errored query would result in automatically refetching that query. -
#11562
65ab695Thanks @mspiess! - Mocks with an infinite delay no longer require result or error
-