# createCartHandler

Creates an API that can be used to interact with the cart.

```js
import {
  createStorefrontClient,
  createCartHandler,
  cartGetIdDefault,
  cartSetIdDefault,
} from '@shopify/hydrogen';
import * as remixBuild from '@remix-run/dev/server-build';
import {
  createRequestHandler,
  getStorefrontHeaders,
} from '@shopify/remix-oxygen';

export default {
  async fetch(request, env, executionContext) {
    const {storefront} = createStorefrontClient({
      /* client parameters */
    });

    // Create a cart api instance.
    const cart = createCartHandler({
      storefront,
      getCartId: cartGetIdDefault(request.headers),
      setCartId: cartSetIdDefault(),
    });

    const handleRequest = createRequestHandler({
      build: remixBuild,
      mode: process.env.NODE_ENV,
      getLoadContext: () => ({
        storefront,
        cart, // Pass the cart api instance to the loader context.
      }),
    });

    return await handleRequest(request);
  },
};

```

```ts
import {
  createStorefrontClient,
  createCartHandler,
  cartGetIdDefault,
  cartSetIdDefault,
} from '@shopify/hydrogen';
import * as remixBuild from '@remix-run/dev/server-build';
import {
  createRequestHandler,
  getStorefrontHeaders,
} from '@shopify/remix-oxygen';

export default {
  async fetch(
    request: Request,
    env: Record<string, string>,
    executionContext: ExecutionContext,
  ): Promise<Response> {
    const {storefront} = createStorefrontClient({
      /* client parameters */
    });

    // Create a cart api instance.
    const cart = createCartHandler({
      storefront,
      getCartId: cartGetIdDefault(request.headers),
      setCartId: cartSetIdDefault(),
    });

    const handleRequest = createRequestHandler({
      build: remixBuild,
      mode: process.env.NODE_ENV,
      getLoadContext: () => ({
        storefront,
        cart, // Pass the cart api instance to the loader context.
      }),
    });

    return await handleRequest(request);
  },
};

```

## createCartHandler(options)

### CartHandlerOptionsForDocs

### getCartId

value: `() => string`

A function that returns the cart id in the form of `gid://shopify/Cart/c1-123`.

### setCartId

value: `(cartId: string) => Headers`

A function that sets the cart ID.

### storefront

value: `Storefront`

The storefront client instance created by [`createStorefrontClient`](docs/api/hydrogen/latest/utilities/createstorefrontclient).

### cartMutateFragment

value: `string`

The cart mutation fragment used in most mutation requests, except for `setMetafields` and `deleteMetafield`. See the [example usage](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/createcarthandler#example-cart-fragments) in the documentation.

### cartQueryFragment

value: `string`

The cart query fragment used by `cart.get()`. See the [example usage](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/createcarthandler#example-cart-fragments) in the documentation.

### customMethods

value: `TCustomMethods`

Define custom methods or override existing methods for your cart API instance. See the [example usage](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/createcarthandler#example-custom-methods) in the documentation.

### Storefront

Interface to interact with the Storefront API.

### query

value: `<OverrideReturnType = any, RawGqlString extends string = string>(query: RawGqlString, ...options: RawGqlString extends never ? IsOptionalVariables<StorefrontQueries[RawGqlString]> extends true ? [StorefrontQuerySecondParam<RawGqlString>?] : [StorefrontQuerySecondParam<RawGqlString>] : [StorefrontQuerySecondParam<string>?]) => Promise<RawGqlString extends never ? StorefrontQueries[RawGqlString]["return"] : OverrideReturnType>`

The function to run a query on Storefront API.

### mutate

value: `<OverrideReturnType = any, RawGqlString extends string = string>(mutation: RawGqlString, ...options: RawGqlString extends never ? IsOptionalVariables<StorefrontMutations[RawGqlString]> extends true ? [StorefrontMutateSecondParam<RawGqlString>?] : [StorefrontMutateSecondParam<RawGqlString>] : [StorefrontCommonOptions<{ readonly [variable: string]: unknown; }>?]) => Promise<RawGqlString extends never ? StorefrontMutations[RawGqlString]["return"] : OverrideReturnType>`

The function to run a mutation on Storefront API.

### cache

value: `Cache`

The cache instance passed in from the `createStorefrontClient` argument.

### CacheNone

value: `() => NoStoreStrategy`

Re-export of [`CacheNone`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachenone).

### CacheLong

value: `(overrideOptions?: AllCacheOptions) => AllCacheOptions`

Re-export of [`CacheLong`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachelong).

### CacheShort

value: `(overrideOptions?: AllCacheOptions) => AllCacheOptions`

Re-export of [`CacheShort`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cacheshort).

### CacheCustom

value: `(overrideOptions: AllCacheOptions) => AllCacheOptions`

Re-export of [`CacheCustom`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachecustom).

### generateCacheControlHeader

value: `(cacheOptions: AllCacheOptions) => string`

Re-export of [`generateCacheControlHeader`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/generatecachecontrolheader).

### getPublicTokenHeaders

value: `(props?: Partial<Pick<StorefrontClientProps, "contentType">> & Pick<StorefrontClientProps, "publicStorefrontToken">) => Record<string, string>`

Returns an object that contains headers that are needed for each query to Storefront API GraphQL endpoint. See [`getPublicTokenHeaders` in Hydrogen React](https://shopify.dev/docs/api/hydrogen-react/2023-10/utilities/createstorefrontclient#:~:text=%27graphql%27.-,getPublicTokenHeaders,-(props%3F%3A) for more details.

### getPrivateTokenHeaders

value: `(props?: Partial<Pick<StorefrontClientProps, "contentType">> & Pick<StorefrontClientProps, "privateStorefrontToken"> & { buyerIp?: string; }) => Record<string, string>`

Returns an object that contains headers that are needed for each query to Storefront API GraphQL endpoint for API calls made from a server. See [`getPrivateTokenHeaders` in  Hydrogen React](https://shopify.dev/docs/api/hydrogen-react/2023-10/utilities/createstorefrontclient#:~:text=storefrontApiVersion-,getPrivateTokenHeaders,-(props%3F%3A) for more details.

### getShopifyDomain

value: `(props?: Partial<Pick<StorefrontClientProps, "storeDomain">>) => string`

Creates the fully-qualified URL to your myshopify.com domain. See [`getShopifyDomain` in  Hydrogen React](https://shopify.dev/docs/api/hydrogen-react/2023-10/utilities/createstorefrontclient#:~:text=StorefrontClientReturn-,getShopifyDomain,-(props%3F%3A) for more details.

### getApiUrl

value: `(props?: Partial<Pick<StorefrontClientProps, "storeDomain" | "storefrontApiVersion">>) => string`

Creates the fully-qualified URL to your store's GraphQL endpoint. See [`getStorefrontApiUrl` in  Hydrogen React](https://shopify.dev/docs/api/hydrogen-react/2023-10/utilities/createstorefrontclient#:~:text=storeDomain-,getStorefrontApiUrl,-(props%3F%3A) for more details.

### isApiError

value: `(error: any) => boolean`

Determines if the error is resulted from a Storefront API call.

### i18n

value: `TI18n`

The `i18n` object passed in from the `createStorefrontClient` argument.

### CachingStrategy

Use the `CachingStrategy` to define a custom caching mechanism for your data. Or use one of the pre-defined caching strategies: CacheNone, CacheShort, CacheLong.

### mode

value: `string`

The caching mode, generally `public`, `private`, or `no-store`.

### maxAge

value: `number`

The maximum amount of time in seconds that a resource will be considered fresh. See `max-age` in the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#:~:text=Response%20Directives-,max%2Dage,-The%20max%2Dage).

### staleWhileRevalidate

value: `number`

Indicate that the cache should serve the stale response in the background while revalidating the cache. See `stale-while-revalidate` in the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-while-revalidate).

### sMaxAge

value: `number`

Similar to `maxAge` but specific to shared caches. See `s-maxage` in the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#s-maxage).

### staleIfError

value: `number`

Indicate that the cache should serve the stale response if an error occurs while revalidating the cache. See `stale-if-error` in the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-if-error).

### NoStoreStrategy

### mode

value: `string`


### AllCacheOptions

Override options for a cache strategy.

### mode

value: `string`

The caching mode, generally `public`, `private`, or `no-store`.

### maxAge

value: `number`

The maximum amount of time in seconds that a resource will be considered fresh. See `max-age` in the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#:~:text=Response%20Directives-,max%2Dage,-The%20max%2Dage).

### staleWhileRevalidate

value: `number`

Indicate that the cache should serve the stale response in the background while revalidating the cache. See `stale-while-revalidate` in the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-while-revalidate).

### sMaxAge

value: `number`

Similar to `maxAge` but specific to shared caches. See `s-maxage` in the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#s-maxage).

### staleIfError

value: `number`

Indicate that the cache should serve the stale response if an error occurs while revalidating the cache. See `stale-if-error` in the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-if-error).

## Examples

Creates an API that can be used to interact with the cart.


### Cart fragments

```js
import {
  createCartHandler,
  cartGetIdDefault,
  cartSetIdDefault,
} from '@shopify/hydrogen';

// Override cart fragments
const cart = createCartHandler({
  storefront,
  getCartId: cartGetIdDefault(request.headers),
  setCartId: cartSetIdDefault(),
  cartQueryFragment: CART_QUERY_FRAGMENT,
  cartMutateFragment: CART_MUTATE_FRAGMENT,
});

// cartQueryFragment requirements:
// - Must be named `CartApiQuery`
// - Only have access to the following query variables:
//   - $cartId: ID!
//   - $country: CountryCode
//   - $language: LanguageCode
//   - $numCartLines: Int
const CART_QUERY_FRAGMENT = `#graphql
  fragment CartApiQuery on Cart {
    id
    totalQuantity
    checkoutUrl
    note
  }
`;

// cartMutateFragment requirements:
// - Must be named `CartApiMutation`
// - Only have access to the following query variables:
//   - $cartId: ID!
//   - $country: CountryCode
//   - $language: LanguageCode
const CART_MUTATE_FRAGMENT = `#graphql
  fragment CartApiMutation on Cart {
    id
    totalQuantity
    checkoutUrl
    lines(first: 100) {
      edges {
        node {
          id
          quantity
        }
      }
    }
  }
`;

```


### Custom methods

```js
import {
  createCartHandler,
  cartGetIdDefault,
  cartSetIdDefault,
  cartLinesAddDefault,
  cartLinesRemoveDefault,
} from '@shopify/hydrogen';

const cartQueryOptions = {
  storefront,
  getCartId: cartGetIdDefault(request.headers),
};

const getCartId = cartGetIdDefault(request.headers);

const cart = createCartHandler({
  storefront,
  getCartId,
  setCartId: cartSetIdDefault(),
  customMethods: {
    editInLine: async (addLines, removeLineIds, optionalParams) => {
      // Using Hydrogen default cart query methods
      await cartLinesAddDefault(cartQueryOptions)(addLines, optionalParams);
      return await cartLinesRemoveDefault(cartQueryOptions)(
        removeLineIds,
        optionalParams,
      );
    },
    addLines: async (lines, optionalParams) => {
      // With your own Storefront API graphql query
      return await storefront.mutate(CART_LINES_ADD_MUTATION, {
        variables: {
          id: optionalParams.cartId || getCartId(),
          lines,
        },
      });
    },
  },
});

// Use custom method editInLine that delete and add items in one method
cart.editInLine(
  ['123'],
  [
    {
      merchandiseId: 'gid://shopify/ProductVariant/456789123',
      quantity: 1,
    },
  ],
);

// Use overridden cart.addLines
const result = await cart.addLines(
  [
    {
      merchandiseId: 'gid://shopify/ProductVariant/123456789',
      quantity: 1,
    },
  ],
  {
    cartId: 'c-123',
  },
);
// Output of result:
// {
//   cartLinesAdd: {
//     cart: {
//       id: 'c-123',
//       totalQuantity: 1
//     },
//     errors: []
//   }
// }

const CART_LINES_ADD_MUTATION = `#graphql
  mutation CartLinesAdd(
    $cartId: ID!
    $lines: [CartLineInput!]!
    $country: CountryCode = ZZ
    $language: LanguageCode
  ) @inContext(country: $country, language: $language) {
    cartLinesAdd(cartId: $cartId, lines: $lines) {
      cart {
        id
        totalQuantity
      }
      errors: userErrors {
        message
        field
        code
      }
    }
  }
`;

```


### Cart instance usage

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.addLines(
    [
      {
        merchandiseId: 'gid://shopify/ProductVariant/123456789',
        quantity: 1,
      },
    ],
    // Optional parameters
    {
      cartId: '123', // override the cart id
      country: 'US', // override the country code to 'US'
      language: 'EN', // override the language code to 'EN'
    },
  );
}

// Output of result:
// {
//   cart: {
//     id: 'c1-123',
//     totalQuantity: 1
//   },
//   errors: []
// }

```

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.create(
    {
      lines: [
        {
          merchandiseId: 'gid://shopify/ProductVariant/123456789',
          quantity: 1,
        },
      ],
      discountCodes: ['FREE_SHIPPING'],
    },
    // Optional parameters
    {
      cartId: '123', // override the cart id
      country: 'US', // override the country code to 'US'
      language: 'EN', // override the language code to 'EN'
    },
  );

  // Output of result:
  // {
  //   cart: {
  //     id: 'c1-123',
  //     totalQuantity: 1,
  //     discountCodes: [{ code: 'FREE_SHIPPING'}]
  //   },
  //   errors: []
  // }
}

```

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.setMetafields(
    [
      {
        key: 'custom.gift',
        type: 'boolean',
        value: 'true',
      },
    ],
    // Optional parameters
    {
      cartId: '123', // override the cart id
    },
  );

  const result2 = await cart.deleteMetafield(
    'custom.gift',
    // Optional parameters
    {
      cartId: '123', // override the cart id
    },
  );
}

// server.js
// To query for metafields, use the `cartQueryFragment` option when creating the cart handler.
import {
  createCartHandler,
  cartGetIdDefault,
  cartSetIdDefault,
} from '@shopify/hydrogen';

const cart = createCartHandler({
  storefront,
  getCartId: cartGetIdDefault(request.headers),
  setCartId: cartSetIdDefault(),
  cartQueryFragment: CART_QUERY_FRAGMENT,
});

const CART_QUERY_FRAGMENT = `#graphql
  fragment CartApiQuery on Cart {
    id
    metafields(
      identifiers: [{
        namespace: "custom",
        key: "gift"
      ])
    {
      namespace
      key
      type
      value
    }

  }
`;

```

```js
export async function loader({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.get();

  // Optional parameters
  const result2 = await cart.get({
    cartId: '123', // override the cart id
    numCartLines: 50, //override to return 50 cart lines
    country: 'US', // override the country code to 'US'
    language: 'EN', // override the language code to 'EN'
  });
}

```

```js
export async function loader({context}) {
  // Usage
  context.cart.getCartId(); // 'gid://shopify/Cart/123'
}

```

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.removeLines(
    ['123'],
    // Optional parameters
    {
      cartId: '123', // override the cart id
      country: 'US', // override the country code to 'US'
      language: 'EN', // override the language code to 'EN'
    },
  );

  // Output of result:
  // {
  //   cart: {
  //     id: 'c1-123',
  //     totalQuantity: 0
  //   },
  //   errors: []
  // }
}

```

```js
export async function action({context}) {
  const {cart} = context;

  const result = await cart.addLines([
    {
      merchandiseId: 'gid://shopify/ProductVariant/123456789',
      quantity: 1,
    },
  ]);

  // Usage
  const headers = cart.setCartId(result.cart.id);
}

```

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.setMetafields(
    [
      {
        key: 'custom.gift',
        type: 'boolean',
        value: 'true',
      },
    ],
    // Optional parameters
    {
      cartId: '123', // override the cart id
    },
  );

  const result2 = await cart.deleteMetafield(
    'custom.gift',
    // Optional parameters
    {
      cartId: '123', // override the cart id
    },
  );
}

// server.js
// To query for metafields, use the `cartQueryFragment` option when creating the cart handler.
import {
  createCartHandler,
  cartGetIdDefault,
  cartSetIdDefault,
} from '@shopify/hydrogen';

const cart = createCartHandler({
  storefront,
  getCartId: cartGetIdDefault(request.headers),
  setCartId: cartSetIdDefault(),
  cartQueryFragment: CART_QUERY_FRAGMENT,
});

const CART_QUERY_FRAGMENT = `#graphql
  fragment CartApiQuery on Cart {
    id
    metafields(
      identifiers: [{
        namespace: "custom",
        key: "gift"
      ])
    {
      namespace
      key
      type
      value
    }

  }
`;

```

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.updateAttributes(
    [
      {
        key: 'Somekey',
        value: '1',
      },
    ],
    // Optional parameters
    {
      cartId: '123', // override the cart id
    },
  );

  // Output of result:
  // {
  //   cart: {
  //     id: 'c1-123',
  //     totalQuantity: 1
  //   },
  //   errors: []
  // }
}

```

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.updateBuyerIdentity(
    {
      customerAccessToken: '123',
    },
    // Optional parameters
    {
      cartId: '123', // override the cart id
      country: 'US', // override the country code to 'US'
      language: 'EN', // override the language code to 'EN'
    },
  );

  // Output of result:
  // {
  //   cart: {
  //     id: 'c1-123',
  //     totalQuantity: 1
  //   },
  //   errors: []
  // }
}

```

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.updateDiscountCodes(
    ['FREE_SHIPPING'],
    // Optional parameters
    {
      cartId: '123', // override the cart id
      country: 'US', // override the country code to 'US'
      language: 'EN', // override the language code to 'EN'
    },
  );

  // Output of result:
  // {
  //   cart: {
  //     id: 'c1-123',
  //     totalQuantity: 1
  //   },
  //   errors: []
  // }
}

```

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.updateLines(
    [
      {
        merchandiseId: 'gid://shopify/ProductVariant/123456789',
        quantity: 2,
      },
    ],
    // Optional parameters
    {
      cartId: '123', // override the cart id
      country: 'US', // override the country code to 'US'
      language: 'EN', // override the language code to 'EN'
    },
  );

  // Output of result:
  // {
  //   cart: {
  //     id: 'c1-123',
  //     totalQuantity: 2
  //   },
  //   errors: []
  // }
}

```

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.updateNote(
    'Some notes',
    // Optional parameters
    {
      cartId: '123', // override the cart id
    },
  );

  // Output of result:
  // {
  //   cart: {
  //     id: 'c1-123',
  //     totalQuantity: 0
  //   },
  //   errors: []
  // }
}

```

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.updateSelectedDeliveryOptions(
    [
      {
        deliveryGroupId: '123',
        deliveryOptionHandle: 'Canada Post',
      },
    ],
    // Optional parameters
    {
      cartId: '123', // override the cart id
      country: 'US', // override the country code to 'US'
      language: 'EN', // override the language code to 'EN'
    },
  );

  // Output of result:
  // {
  //   cart: {
  //     id: 'c1-123',
  //     totalQuantity: 2
  //   },
  //   errors: []
  // }
}

```

## Returns

The handler returns the following default methods. Any [custom](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/createcarthandler#example-custom-methods) or overwritten methods will also be available in the returned cart instance.

### HydrogenCartForDocs

### addLines

value: `CartLinesAddFunction`

Adds items to the cart. If the cart doesn't exist, a new one will be created.

### create

value: `CartCreateFunction`

Creates a new cart.

### deleteMetafield

value: `CartMetafieldDeleteFunction`

Removes a custom field (metafield) from the cart.

### get

value: `CartGetFunction`

Retrieves the cart information.

### getCartId

value: `() => string`

Retrieves the unique identifier of the cart. By default, it gets the ID from the request cookie.

### removeLines

value: `CartLinesRemoveFunction`

Removes items from the cart.

### setCartId

value: `(cartId: string) => Headers`

Sets the unique identifier of the cart. By default, it sets the ID in the header cookie.

### setMetafields

value: `CartMetafieldsSetFunction`

Adds extra information (metafields) to the cart. If the cart doesn't exist, a new one will be created.

### updateAttributes

value: `CartAttributesUpdateFunction`

Updates additional information (attributes) in the cart.

### updateBuyerIdentity

value: `CartBuyerIdentityUpdateFunction`

Updates the buyer's information in the cart. If the cart doesn't exist, a new one will be created.

### updateDiscountCodes

value: `CartDiscountCodesUpdateFunction`

Updates discount codes in the cart.

### updateLines

value: `CartLinesUpdateFunction`

Updates items in the cart.

### updateNote

value: `CartNoteUpdateFunction`

Updates the note in the cart. If the cart doesn't exist, a new one will be created.

### updateSelectedDeliveryOption

value: `CartSelectedDeliveryOptionsUpdateFunction`

Updates the selected delivery options in the cart. Only available for carts associated with a customer access token.

### CartLinesAddFunction

#### Returns: Promise<CartQueryData>

#### Params:

- lines: CartLineInput[]
- optionalParams: CartOptionalInput
export type CartLinesAddFunction = (
  lines: CartLineInput[],
  optionalParams?: CartOptionalInput,
) => Promise<CartQueryData>;


### CartOptionalInput

### cartId

value: `string`

The cart id.

### country

value: `CountryCode`

The country code.

### language

value: `LanguageCode`

The language code.

### CartQueryData

### cart

value: `Cart`


### errors

value: `CartUserError[] | MetafieldsSetUserError[] | MetafieldDeleteUserError[]`


### CartCreateFunction

#### Returns: Promise<CartQueryData>

#### Params:

- input: CartInput
- optionalParams: CartOptionalInput
export type CartCreateFunction = (
  input: CartInput,
  optionalParams?: CartOptionalInput,
) => Promise<CartQueryData>;


### CartMetafieldDeleteFunction

#### Returns: Promise<CartQueryData>

#### Params:

- key: string
- optionalParams: CartOptionalInput
export type CartMetafieldDeleteFunction = (
  key: Scalars['String']['input'],
  optionalParams?: CartOptionalInput,
) => Promise<CartQueryData>;


### CartGetFunction

#### Returns: Promise<Cart | null>

#### Params:

- cartInput: CartGetProps
export type CartGetFunction = (
  cartInput?: CartGetProps,
) => Promise<Cart | null>;


### CartGetProps

### cartId

value: `string`

The cart ID.

### country

value: `CountryCode`

The country code.

### language

value: `LanguageCode`

The language code.

### numCartLines

value: `number`

The number of cart lines to be returned.

### CartLinesRemoveFunction

#### Returns: Promise<CartQueryData>

#### Params:

- lineIds: string[]
- optionalParams: CartOptionalInput
export type CartLinesRemoveFunction = (
  lineIds: string[],
  optionalParams?: CartOptionalInput,
) => Promise<CartQueryData>;


### CartMetafieldsSetFunction

#### Returns: Promise<CartQueryData>

#### Params:

- metafields: MetafieldWithoutOwnerId[]
- optionalParams: CartOptionalInput
export type CartMetafieldsSetFunction = (
  metafields: MetafieldWithoutOwnerId[],
  optionalParams?: CartOptionalInput,
) => Promise<CartQueryData>;


### CartAttributesUpdateFunction

#### Returns: Promise<CartQueryData>

#### Params:

- attributes: AttributeInput[]
- optionalParams: CartOptionalInput
export type CartAttributesUpdateFunction = (
  attributes: AttributeInput[],
  optionalParams?: CartOptionalInput,
) => Promise<CartQueryData>;


### CartBuyerIdentityUpdateFunction

#### Returns: Promise<CartQueryData>

#### Params:

- buyerIdentity: CartBuyerIdentityInput
- optionalParams: CartOptionalInput
export type CartBuyerIdentityUpdateFunction = (
  buyerIdentity: CartBuyerIdentityInput,
  optionalParams?: CartOptionalInput,
) => Promise<CartQueryData>;


### CartDiscountCodesUpdateFunction

#### Returns: Promise<CartQueryData>

#### Params:

- discountCodes: string[]
- optionalParams: CartOptionalInput
export type CartDiscountCodesUpdateFunction = (
  discountCodes: string[],
  optionalParams?: CartOptionalInput,
) => Promise<CartQueryData>;


### CartLinesUpdateFunction

#### Returns: Promise<CartQueryData>

#### Params:

- lines: CartLineUpdateInput[]
- optionalParams: CartOptionalInput
export type CartLinesUpdateFunction = (
  lines: CartLineUpdateInput[],
  optionalParams?: CartOptionalInput,
) => Promise<CartQueryData>;


### CartNoteUpdateFunction

#### Returns: Promise<CartQueryData>

#### Params:

- note: string
- optionalParams: CartOptionalInput
export type CartNoteUpdateFunction = (
  note: string,
  optionalParams?: CartOptionalInput,
) => Promise<CartQueryData>;


### CartSelectedDeliveryOptionsUpdateFunction

#### Returns: Promise<CartQueryData>

#### Params:

- selectedDeliveryOptions: CartSelectedDeliveryOptionInput[]
- optionalParams: CartOptionalInput
export type CartSelectedDeliveryOptionsUpdateFunction = (
  selectedDeliveryOptions: CartSelectedDeliveryOptionInput[],
  optionalParams?: CartOptionalInput,
) => Promise<CartQueryData>;


## Examples

Creates an API that can be used to interact with the cart.


### Cart fragments

```js
import {
  createCartHandler,
  cartGetIdDefault,
  cartSetIdDefault,
} from '@shopify/hydrogen';

// Override cart fragments
const cart = createCartHandler({
  storefront,
  getCartId: cartGetIdDefault(request.headers),
  setCartId: cartSetIdDefault(),
  cartQueryFragment: CART_QUERY_FRAGMENT,
  cartMutateFragment: CART_MUTATE_FRAGMENT,
});

// cartQueryFragment requirements:
// - Must be named `CartApiQuery`
// - Only have access to the following query variables:
//   - $cartId: ID!
//   - $country: CountryCode
//   - $language: LanguageCode
//   - $numCartLines: Int
const CART_QUERY_FRAGMENT = `#graphql
  fragment CartApiQuery on Cart {
    id
    totalQuantity
    checkoutUrl
    note
  }
`;

// cartMutateFragment requirements:
// - Must be named `CartApiMutation`
// - Only have access to the following query variables:
//   - $cartId: ID!
//   - $country: CountryCode
//   - $language: LanguageCode
const CART_MUTATE_FRAGMENT = `#graphql
  fragment CartApiMutation on Cart {
    id
    totalQuantity
    checkoutUrl
    lines(first: 100) {
      edges {
        node {
          id
          quantity
        }
      }
    }
  }
`;

```


### Custom methods

```js
import {
  createCartHandler,
  cartGetIdDefault,
  cartSetIdDefault,
  cartLinesAddDefault,
  cartLinesRemoveDefault,
} from '@shopify/hydrogen';

const cartQueryOptions = {
  storefront,
  getCartId: cartGetIdDefault(request.headers),
};

const getCartId = cartGetIdDefault(request.headers);

const cart = createCartHandler({
  storefront,
  getCartId,
  setCartId: cartSetIdDefault(),
  customMethods: {
    editInLine: async (addLines, removeLineIds, optionalParams) => {
      // Using Hydrogen default cart query methods
      await cartLinesAddDefault(cartQueryOptions)(addLines, optionalParams);
      return await cartLinesRemoveDefault(cartQueryOptions)(
        removeLineIds,
        optionalParams,
      );
    },
    addLines: async (lines, optionalParams) => {
      // With your own Storefront API graphql query
      return await storefront.mutate(CART_LINES_ADD_MUTATION, {
        variables: {
          id: optionalParams.cartId || getCartId(),
          lines,
        },
      });
    },
  },
});

// Use custom method editInLine that delete and add items in one method
cart.editInLine(
  ['123'],
  [
    {
      merchandiseId: 'gid://shopify/ProductVariant/456789123',
      quantity: 1,
    },
  ],
);

// Use overridden cart.addLines
const result = await cart.addLines(
  [
    {
      merchandiseId: 'gid://shopify/ProductVariant/123456789',
      quantity: 1,
    },
  ],
  {
    cartId: 'c-123',
  },
);
// Output of result:
// {
//   cartLinesAdd: {
//     cart: {
//       id: 'c-123',
//       totalQuantity: 1
//     },
//     errors: []
//   }
// }

const CART_LINES_ADD_MUTATION = `#graphql
  mutation CartLinesAdd(
    $cartId: ID!
    $lines: [CartLineInput!]!
    $country: CountryCode = ZZ
    $language: LanguageCode
  ) @inContext(country: $country, language: $language) {
    cartLinesAdd(cartId: $cartId, lines: $lines) {
      cart {
        id
        totalQuantity
      }
      errors: userErrors {
        message
        field
        code
      }
    }
  }
`;

```


### Cart instance usage

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.addLines(
    [
      {
        merchandiseId: 'gid://shopify/ProductVariant/123456789',
        quantity: 1,
      },
    ],
    // Optional parameters
    {
      cartId: '123', // override the cart id
      country: 'US', // override the country code to 'US'
      language: 'EN', // override the language code to 'EN'
    },
  );
}

// Output of result:
// {
//   cart: {
//     id: 'c1-123',
//     totalQuantity: 1
//   },
//   errors: []
// }

```

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.create(
    {
      lines: [
        {
          merchandiseId: 'gid://shopify/ProductVariant/123456789',
          quantity: 1,
        },
      ],
      discountCodes: ['FREE_SHIPPING'],
    },
    // Optional parameters
    {
      cartId: '123', // override the cart id
      country: 'US', // override the country code to 'US'
      language: 'EN', // override the language code to 'EN'
    },
  );

  // Output of result:
  // {
  //   cart: {
  //     id: 'c1-123',
  //     totalQuantity: 1,
  //     discountCodes: [{ code: 'FREE_SHIPPING'}]
  //   },
  //   errors: []
  // }
}

```

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.setMetafields(
    [
      {
        key: 'custom.gift',
        type: 'boolean',
        value: 'true',
      },
    ],
    // Optional parameters
    {
      cartId: '123', // override the cart id
    },
  );

  const result2 = await cart.deleteMetafield(
    'custom.gift',
    // Optional parameters
    {
      cartId: '123', // override the cart id
    },
  );
}

// server.js
// To query for metafields, use the `cartQueryFragment` option when creating the cart handler.
import {
  createCartHandler,
  cartGetIdDefault,
  cartSetIdDefault,
} from '@shopify/hydrogen';

const cart = createCartHandler({
  storefront,
  getCartId: cartGetIdDefault(request.headers),
  setCartId: cartSetIdDefault(),
  cartQueryFragment: CART_QUERY_FRAGMENT,
});

const CART_QUERY_FRAGMENT = `#graphql
  fragment CartApiQuery on Cart {
    id
    metafields(
      identifiers: [{
        namespace: "custom",
        key: "gift"
      ])
    {
      namespace
      key
      type
      value
    }

  }
`;

```

```js
export async function loader({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.get();

  // Optional parameters
  const result2 = await cart.get({
    cartId: '123', // override the cart id
    numCartLines: 50, //override to return 50 cart lines
    country: 'US', // override the country code to 'US'
    language: 'EN', // override the language code to 'EN'
  });
}

```

```js
export async function loader({context}) {
  // Usage
  context.cart.getCartId(); // 'gid://shopify/Cart/123'
}

```

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.removeLines(
    ['123'],
    // Optional parameters
    {
      cartId: '123', // override the cart id
      country: 'US', // override the country code to 'US'
      language: 'EN', // override the language code to 'EN'
    },
  );

  // Output of result:
  // {
  //   cart: {
  //     id: 'c1-123',
  //     totalQuantity: 0
  //   },
  //   errors: []
  // }
}

```

```js
export async function action({context}) {
  const {cart} = context;

  const result = await cart.addLines([
    {
      merchandiseId: 'gid://shopify/ProductVariant/123456789',
      quantity: 1,
    },
  ]);

  // Usage
  const headers = cart.setCartId(result.cart.id);
}

```

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.setMetafields(
    [
      {
        key: 'custom.gift',
        type: 'boolean',
        value: 'true',
      },
    ],
    // Optional parameters
    {
      cartId: '123', // override the cart id
    },
  );

  const result2 = await cart.deleteMetafield(
    'custom.gift',
    // Optional parameters
    {
      cartId: '123', // override the cart id
    },
  );
}

// server.js
// To query for metafields, use the `cartQueryFragment` option when creating the cart handler.
import {
  createCartHandler,
  cartGetIdDefault,
  cartSetIdDefault,
} from '@shopify/hydrogen';

const cart = createCartHandler({
  storefront,
  getCartId: cartGetIdDefault(request.headers),
  setCartId: cartSetIdDefault(),
  cartQueryFragment: CART_QUERY_FRAGMENT,
});

const CART_QUERY_FRAGMENT = `#graphql
  fragment CartApiQuery on Cart {
    id
    metafields(
      identifiers: [{
        namespace: "custom",
        key: "gift"
      ])
    {
      namespace
      key
      type
      value
    }

  }
`;

```

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.updateAttributes(
    [
      {
        key: 'Somekey',
        value: '1',
      },
    ],
    // Optional parameters
    {
      cartId: '123', // override the cart id
    },
  );

  // Output of result:
  // {
  //   cart: {
  //     id: 'c1-123',
  //     totalQuantity: 1
  //   },
  //   errors: []
  // }
}

```

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.updateBuyerIdentity(
    {
      customerAccessToken: '123',
    },
    // Optional parameters
    {
      cartId: '123', // override the cart id
      country: 'US', // override the country code to 'US'
      language: 'EN', // override the language code to 'EN'
    },
  );

  // Output of result:
  // {
  //   cart: {
  //     id: 'c1-123',
  //     totalQuantity: 1
  //   },
  //   errors: []
  // }
}

```

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.updateDiscountCodes(
    ['FREE_SHIPPING'],
    // Optional parameters
    {
      cartId: '123', // override the cart id
      country: 'US', // override the country code to 'US'
      language: 'EN', // override the language code to 'EN'
    },
  );

  // Output of result:
  // {
  //   cart: {
  //     id: 'c1-123',
  //     totalQuantity: 1
  //   },
  //   errors: []
  // }
}

```

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.updateLines(
    [
      {
        merchandiseId: 'gid://shopify/ProductVariant/123456789',
        quantity: 2,
      },
    ],
    // Optional parameters
    {
      cartId: '123', // override the cart id
      country: 'US', // override the country code to 'US'
      language: 'EN', // override the language code to 'EN'
    },
  );

  // Output of result:
  // {
  //   cart: {
  //     id: 'c1-123',
  //     totalQuantity: 2
  //   },
  //   errors: []
  // }
}

```

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.updateNote(
    'Some notes',
    // Optional parameters
    {
      cartId: '123', // override the cart id
    },
  );

  // Output of result:
  // {
  //   cart: {
  //     id: 'c1-123',
  //     totalQuantity: 0
  //   },
  //   errors: []
  // }
}

```

```js
export async function action({context}) {
  const {cart} = context;

  // Usage
  const result = await cart.updateSelectedDeliveryOptions(
    [
      {
        deliveryGroupId: '123',
        deliveryOptionHandle: 'Canada Post',
      },
    ],
    // Optional parameters
    {
      cartId: '123', // override the cart id
      country: 'US', // override the country code to 'US'
      language: 'EN', // override the language code to 'EN'
    },
  );

  // Output of result:
  // {
  //   cart: {
  //     id: 'c1-123',
  //     totalQuantity: 2
  //   },
  //   errors: []
  // }
}

```