diff --git a/.changeset/delivery-address-replace-mutation.md b/.changeset/delivery-address-replace-mutation.md
new file mode 100644
index 0000000000..2736ca6c06
--- /dev/null
+++ b/.changeset/delivery-address-replace-mutation.md
@@ -0,0 +1,30 @@
+---
+'@shopify/hydrogen': minor
+---
+
+Add `cartDeliveryAddressesReplaceDefault` to handle the new `cartDeliveryAddressesReplace` Storefront API mutation (2025-10)
+
+This new mutation replaces all delivery addresses on a cart in a single operation.
+
+**Usage via cart handler:**
+```typescript
+const result = await cart.replaceDeliveryAddresses([
+ {
+ address: {
+ deliveryAddress: {
+ address1: '123 Main St',
+ city: 'Anytown',
+ countryCode: 'US'
+ }
+ },
+ selected: true
+ }
+]);
+```
+
+**Usage via CartForm:**
+```tsx
+
+ {/* form inputs */}
+
+```
diff --git a/packages/hydrogen/src/cart/CartForm.test.tsx b/packages/hydrogen/src/cart/CartForm.test.tsx
index e581ce0114..31eb622b37 100644
--- a/packages/hydrogen/src/cart/CartForm.test.tsx
+++ b/packages/hydrogen/src/cart/CartForm.test.tsx
@@ -85,6 +85,7 @@ describe('', () => {
DeliveryAddressesAdd: 'DeliveryAddressesAdd',
DeliveryAddressesUpdate: 'DeliveryAddressesUpdate',
DeliveryAddressesRemove: 'DeliveryAddressesRemove',
+ DeliveryAddressesReplace: 'DeliveryAddressesReplace',
DiscountCodesUpdate: 'DiscountCodesUpdate',
GiftCardCodesUpdate: 'GiftCardCodesUpdate',
GiftCardCodesRemove: 'GiftCardCodesRemove',
diff --git a/packages/hydrogen/src/cart/CartForm.tsx b/packages/hydrogen/src/cart/CartForm.tsx
index 5e5d92c985..e083031075 100644
--- a/packages/hydrogen/src/cart/CartForm.tsx
+++ b/packages/hydrogen/src/cart/CartForm.tsx
@@ -245,6 +245,20 @@ type CartDeliveryAddressesUpdateRequire = {
} & OtherFormData;
};
+type CartDeliveryAddressesReplaceProps = {
+ action: 'DeliveryAddressesReplace';
+ inputs?: {
+ addresses: Array;
+ } & OtherFormData;
+};
+
+type CartDeliveryAddressesReplaceRequire = {
+ action: 'DeliveryAddressesReplace';
+ inputs: {
+ addresses: Array;
+ } & OtherFormData;
+};
+
type CartCustomProps = {
action: `Custom${string}`;
inputs?: Record;
@@ -289,6 +303,7 @@ type CartActionInputProps =
| CartDeliveryAddressesAddProps
| CartDeliveryAddressesRemoveProps
| CartDeliveryAddressesUpdateProps
+ | CartDeliveryAddressesReplaceProps
| CartCustomProps;
export type CartActionInput =
@@ -308,6 +323,7 @@ export type CartActionInput =
| CartDeliveryAddressesAddRequire
| CartDeliveryAddressesRemoveRequire
| CartDeliveryAddressesUpdateRequire
+ | CartDeliveryAddressesReplaceRequire
| CartCustomRequire;
type CartFormProps = CartActionInputProps & CartFormCommonProps;
@@ -356,6 +372,7 @@ CartForm.ACTIONS = {
DeliveryAddressesAdd: 'DeliveryAddressesAdd',
DeliveryAddressesUpdate: 'DeliveryAddressesUpdate',
DeliveryAddressesRemove: 'DeliveryAddressesRemove',
+ DeliveryAddressesReplace: 'DeliveryAddressesReplace',
} as const;
function getFormInput(formData: FormData): CartActionInput {
diff --git a/packages/hydrogen/src/cart/createCartHandler.test.ts b/packages/hydrogen/src/cart/createCartHandler.test.ts
index 1d3a0318bb..3013c9fc9b 100644
--- a/packages/hydrogen/src/cart/createCartHandler.test.ts
+++ b/packages/hydrogen/src/cart/createCartHandler.test.ts
@@ -37,7 +37,7 @@ describe('createCartHandler', () => {
const cart = getCartHandler();
expectTypeOf(cart).toEqualTypeOf;
- expect(Object.keys(cart)).toHaveLength(19);
+ expect(Object.keys(cart)).toHaveLength(20);
expect(cart).toHaveProperty('get');
expect(cart).toHaveProperty('getCartId');
expect(cart).toHaveProperty('setCartId');
@@ -57,6 +57,7 @@ describe('createCartHandler', () => {
expect(cart).toHaveProperty('addDeliveryAddresses');
expect(cart).toHaveProperty('removeDeliveryAddresses');
expect(cart).toHaveProperty('updateDeliveryAddresses');
+ expect(cart).toHaveProperty('replaceDeliveryAddresses');
});
it('can add custom methods', () => {
@@ -72,7 +73,7 @@ describe('createCartHandler', () => {
});
expectTypeOf(cart).toEqualTypeOf 'bar'}>>;
- expect(Object.keys(cart)).toHaveLength(20);
+ expect(Object.keys(cart)).toHaveLength(21);
expect(cart.foo()).toBe('bar');
});
@@ -86,7 +87,7 @@ describe('createCartHandler', () => {
});
expectTypeOf(cart).toEqualTypeOf;
- expect(Object.keys(cart)).toHaveLength(19);
+ expect(Object.keys(cart)).toHaveLength(20);
expect(await cart.get()).toBe('bar');
});
diff --git a/packages/hydrogen/src/cart/createCartHandler.ts b/packages/hydrogen/src/cart/createCartHandler.ts
index b3a3954765..c0c46003e3 100644
--- a/packages/hydrogen/src/cart/createCartHandler.ts
+++ b/packages/hydrogen/src/cart/createCartHandler.ts
@@ -65,6 +65,10 @@ import {
type CartDeliveryAddressesUpdateFunction,
cartDeliveryAddressesUpdateDefault,
} from './queries/cartDeliveryAddressesUpdateDefault';
+import {
+ type CartDeliveryAddressesReplaceFunction,
+ cartDeliveryAddressesReplaceDefault,
+} from './queries/cartDeliveryAddressesReplaceDefault';
import type {CartBuyerIdentityInput} from '@shopify/hydrogen-react/storefront-api-types';
export type CartHandlerOptions = {
@@ -180,6 +184,32 @@ export type HydrogenCart = {
updateDeliveryAddresses: ReturnType<
typeof cartDeliveryAddressesUpdateDefault
>;
+ /**
+ * Replaces all delivery addresses on the cart.
+ *
+ * This function sends a mutation to the storefront API to replace all delivery addresses on the cart
+ * with the provided addresses. It returns the result of the mutation, including any errors that occurred.
+ *
+ * @param {CartQueryOptions} options - The options for the cart query, including the storefront API client and cart fragment.
+ * @returns {CartDeliveryAddressesReplaceFunction} - A function that takes an array of addresses and optional parameters, and returns the result of the API call.
+ *
+ * @example
+ * const result = await cart.replaceDeliveryAddresses([
+ * {
+ * address: {
+ * deliveryAddress: {
+ * address1: '123 Main St',
+ * city: 'Anytown',
+ * countryCode: 'US'
+ * }
+ * },
+ * selected: true
+ * }
+ * ], { someOptionalParam: 'value' });
+ */
+ replaceDeliveryAddresses: ReturnType<
+ typeof cartDeliveryAddressesReplaceDefault
+ >;
};
export type HydrogenCartCustom<
@@ -310,6 +340,8 @@ export function createCartHandler(
addDeliveryAddresses: cartDeliveryAddressesAddDefault(mutateOptions),
removeDeliveryAddresses: cartDeliveryAddressesRemoveDefault(mutateOptions),
updateDeliveryAddresses: cartDeliveryAddressesUpdateDefault(mutateOptions),
+ replaceDeliveryAddresses:
+ cartDeliveryAddressesReplaceDefault(mutateOptions),
};
if ('customMethods' in options) {
@@ -408,6 +440,10 @@ export type HydrogenCartForDocs = {
* Update cart delivery addresses.
*/
updateDeliveryAddresses?: CartDeliveryAddressesUpdateFunction;
+ /**
+ * Replace all delivery addresses on the cart.
+ */
+ replaceDeliveryAddresses?: CartDeliveryAddressesReplaceFunction;
/**
* Updates additional information (attributes) in the cart.
*/
diff --git a/packages/hydrogen/src/cart/queries/cartDeliveryAddressesReplaceDefault.doc.ts b/packages/hydrogen/src/cart/queries/cartDeliveryAddressesReplaceDefault.doc.ts
new file mode 100644
index 0000000000..c4d6ddf65e
--- /dev/null
+++ b/packages/hydrogen/src/cart/queries/cartDeliveryAddressesReplaceDefault.doc.ts
@@ -0,0 +1,35 @@
+import {ReferenceEntityTemplateSchema} from '@shopify/generate-docs';
+
+const data: ReferenceEntityTemplateSchema = {
+ name: 'cartDeliveryAddressesReplace',
+ category: 'utilities',
+ subCategory: 'cart',
+ isVisualComponent: false,
+ related: [],
+ description:
+ 'Creates a function that accepts an array of [CartSelectableAddressInput](/docs/api/storefront/2025-10/input-objects/CartSelectableAddressInput) to replace all delivery addresses on a cart',
+ type: 'utility',
+ defaultExample: {
+ description:
+ 'Replace all delivery addresses on a cart with a new set of addresses',
+ codeblock: {
+ tabs: [
+ {
+ title: 'JavaScript',
+ code: './cartDeliveryAddressesReplaceDefault.example.js',
+ language: 'js',
+ },
+ ],
+ title: 'example',
+ },
+ },
+ definitions: [
+ {
+ title: 'cartDeliveryAddressesReplaceDefault',
+ type: 'CartDeliveryAddressesReplaceDefaultGeneratedType',
+ description: '',
+ },
+ ],
+};
+
+export default data;
diff --git a/packages/hydrogen/src/cart/queries/cartDeliveryAddressesReplaceDefault.example.js b/packages/hydrogen/src/cart/queries/cartDeliveryAddressesReplaceDefault.example.js
new file mode 100644
index 0000000000..0b9fa4fa31
--- /dev/null
+++ b/packages/hydrogen/src/cart/queries/cartDeliveryAddressesReplaceDefault.example.js
@@ -0,0 +1,29 @@
+import {cartDeliveryAddressesReplaceDefault} from '@shopify/hydrogen';
+
+const replaceDeliveryAddresses = cartDeliveryAddressesReplaceDefault({
+ storefront,
+ getCartId,
+});
+
+const result = await replaceDeliveryAddresses(
+ [
+ {
+ address: {
+ deliveryAddress: {
+ address1: '',
+ address2: '',
+ city: '',
+ company: '',
+ countryCode: 'AC',
+ firstName: '',
+ lastName: '',
+ phone: '',
+ provinceCode: '',
+ zip: '',
+ },
+ },
+ selected: true,
+ },
+ ],
+ {someOptionalParam: 'value'},
+);
diff --git a/packages/hydrogen/src/cart/queries/cartDeliveryAddressesReplaceDefault.test.ts b/packages/hydrogen/src/cart/queries/cartDeliveryAddressesReplaceDefault.test.ts
new file mode 100644
index 0000000000..caf28daa1f
--- /dev/null
+++ b/packages/hydrogen/src/cart/queries/cartDeliveryAddressesReplaceDefault.test.ts
@@ -0,0 +1,30 @@
+import {describe, it, expect} from 'vitest';
+import {CART_ID, mockCreateStorefrontClient} from '../cart-test-helper';
+import {cartDeliveryAddressesReplaceDefault} from './cartDeliveryAddressesReplaceDefault';
+
+describe('cartDeliveryAddressesReplaceDefault', () => {
+ it('should return a default cart delivery address replace implementation', async () => {
+ const replaceDeliveryAddresses = cartDeliveryAddressesReplaceDefault({
+ storefront: mockCreateStorefrontClient(),
+ getCartId: () => CART_ID,
+ });
+
+ const result = await replaceDeliveryAddresses([]);
+
+ expect(result.cart).toHaveProperty('id', CART_ID);
+ });
+
+ it('can override cartFragment', async () => {
+ const cartFragment = 'cartFragmentOverride';
+ const replaceDeliveryAddresses = cartDeliveryAddressesReplaceDefault({
+ storefront: mockCreateStorefrontClient(),
+ getCartId: () => CART_ID,
+ cartFragment,
+ });
+
+ const result = await replaceDeliveryAddresses([]);
+
+ expect(result.cart).toHaveProperty('id', CART_ID);
+ expect(result.userErrors?.[0]).toContain(cartFragment);
+ });
+});
diff --git a/packages/hydrogen/src/cart/queries/cartDeliveryAddressesReplaceDefault.tsx b/packages/hydrogen/src/cart/queries/cartDeliveryAddressesReplaceDefault.tsx
new file mode 100644
index 0000000000..e2d6f43086
--- /dev/null
+++ b/packages/hydrogen/src/cart/queries/cartDeliveryAddressesReplaceDefault.tsx
@@ -0,0 +1,93 @@
+import {StorefrontApiErrors, formatAPIResult} from '../../storefront';
+import type {CartSelectableAddressInput} from '@shopify/hydrogen-react/storefront-api-types';
+import {
+ CART_WARNING_FRAGMENT,
+ MINIMAL_CART_FRAGMENT,
+ USER_ERROR_FRAGMENT,
+} from './cart-fragments';
+import type {
+ CartOptionalInput,
+ CartQueryData,
+ CartQueryDataReturn,
+ CartQueryOptions,
+} from './cart-types';
+
+export type CartDeliveryAddressesReplaceFunction = (
+ addresses: Array,
+ optionalParams?: CartOptionalInput,
+) => Promise;
+
+/**
+ * Replaces all delivery addresses on the cart.
+ *
+ * This function sends a mutation to the storefront API to replace all delivery addresses on the cart
+ * with the provided addresses. It returns the result of the mutation, including any errors that occurred.
+ *
+ * @param {CartQueryOptions} options - The options for the cart query, including the storefront API client and cart fragment.
+ * @returns {CartDeliveryAddressesReplaceFunction} - A function that takes an array of addresses and optional parameters, and returns the result of the API call.
+ *
+ * @example
+ * const replaceDeliveryAddresses = cartDeliveryAddressesReplaceDefault({ storefront, getCartId });
+ * const result = await replaceDeliveryAddresses([
+ * {
+ * address: {
+ * deliveryAddress: {
+ * address1: '123 Main St',
+ * city: 'Anytown',
+ * countryCode: 'US'
+ * }
+ * },
+ * selected: true
+ * }
+ * ], { someOptionalParam: 'value' }
+ * );
+ */
+export function cartDeliveryAddressesReplaceDefault(
+ options: CartQueryOptions,
+): CartDeliveryAddressesReplaceFunction {
+ return async (
+ addresses: Array,
+ optionalParams,
+ ) => {
+ const {cartDeliveryAddressesReplace, errors} =
+ await options.storefront.mutate<{
+ cartDeliveryAddressesReplace: CartQueryData;
+ errors: StorefrontApiErrors;
+ }>(CART_DELIVERY_ADDRESSES_REPLACE_MUTATION(options.cartFragment), {
+ variables: {
+ cartId: options.getCartId(),
+ addresses,
+ ...optionalParams,
+ },
+ });
+
+ return formatAPIResult(cartDeliveryAddressesReplace, errors);
+ };
+}
+
+//! @see: https://shopify.dev/docs/api/storefront/2025-10/mutations/cartDeliveryAddressesReplace
+export const CART_DELIVERY_ADDRESSES_REPLACE_MUTATION = (
+ cartFragment = MINIMAL_CART_FRAGMENT,
+) => `#graphql
+ mutation cartDeliveryAddressesReplace(
+ $cartId: ID!
+ $addresses: [CartSelectableAddressInput!]!,
+ $country: CountryCode = ZZ
+ $language: LanguageCode
+ ) @inContext(country: $country, language: $language) {
+ cartDeliveryAddressesReplace(addresses: $addresses, cartId: $cartId) {
+ cart {
+ ...CartApiMutation
+ }
+ userErrors {
+ ...CartApiError
+ }
+ warnings {
+ ...CartApiWarning
+ }
+ }
+ }
+ ${cartFragment}
+ ${USER_ERROR_FRAGMENT}
+ ${CART_WARNING_FRAGMENT}
+`;