---
title: createCartHandler
description: Creates an API that can be used to interact with the cart.
api_version: 2024-01
api_name: hydrogen
source_url:
  html: 'https://shopify.dev/docs/api/hydrogen/2024-01/utilities/createcarthandler'
  md: 'https://shopify.dev/docs/api/hydrogen/2024-01/utilities/createcarthandler.md'
---

# create​Cart​Handler

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

## createCartHandler(options)

* **getCartId**

  **() => string**

  **required**

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

* **setCartId**

  **(cartId: string) => Headers**

  **required**

  A function that sets the cart ID.

* **storefront**

  **Storefront**

  **required**

  The storefront client instance created by [`createStorefrontClient`](https://shopify.dev/docs/api/hydrogen/2024-01/utilities/createcarthandler.md/docs/api/hydrogen/latest/utilities/createstorefrontclient).

* **cartMutateFragment**

  **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/2024-01/utilities/createcarthandler#example-cart-fragments) in the documentation.

* **cartQueryFragment**

  **string**

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

* **customMethods**

  **TCustomMethods**

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

### Headers



### Storefront

Interface to interact with the Storefront API.

* query

  ```ts
  <OverrideReturnType extends unknown = never, RawGqlString extends string = string>(query: RawGqlString, ...options: IsOptionalVariables<StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames, Omit<StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>> extends true ? [(StorefrontCommonExtraParams & Pick<StorefrontQueryOptions, "cache"> & ClientVariables<StorefrontQueries, RawGqlString, AutoAddedVariableNames, "variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof StorefrontQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontQueries[RawGqlString]["variables"], Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>>)]: ({ [KeyType in keyof StorefrontQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontQueries[RawGqlString]["variables"], Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>>)[KeyType]; } : { readonly [variable: string]: unknown; }, Record<"variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof StorefrontQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontQueries[RawGqlString]["variables"], Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>>)]: ({ [KeyType in keyof StorefrontQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontQueries[RawGqlString]["variables"], Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>>)[KeyType]; } : { readonly [variable: string]: unknown; }>>)?] : [StorefrontCommonExtraParams & Pick<StorefrontQueryOptions, "cache"> & ClientVariables<StorefrontQueries, RawGqlString, AutoAddedVariableNames, "variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof StorefrontQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontQueries[RawGqlString]["variables"], Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>>)]: ({ [KeyType in keyof StorefrontQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontQueries[RawGqlString]["variables"], Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>>)[KeyType]; } : { readonly [variable: string]: unknown; }, Record<"variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof StorefrontQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontQueries[RawGqlString]["variables"], Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>>)]: ({ [KeyType in keyof StorefrontQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontQueries[RawGqlString]["variables"], Extract<keyof StorefrontQueries[RawGqlString]["variables"], AutoAddedVariableNames>>>)[KeyType]; } : { readonly [variable: string]: unknown; }>>]) => Promise<ClientReturn<StorefrontQueries, RawGqlString, OverrideReturnType> & StorefrontError>
  ```

* mutate

  ```ts
  <OverrideReturnType extends unknown = never, RawGqlString extends string = string>(mutation: RawGqlString, ...options: IsOptionalVariables<StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames, Omit<StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>> extends true ? [(StorefrontCommonExtraParams & ClientVariables<StorefrontMutations, RawGqlString, AutoAddedVariableNames, "variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof StorefrontMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontMutations[RawGqlString]["variables"], Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>>)]: ({ [KeyType in keyof StorefrontMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontMutations[RawGqlString]["variables"], Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>>)[KeyType]; } : { readonly [variable: string]: unknown; }, Record<"variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof StorefrontMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontMutations[RawGqlString]["variables"], Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>>)]: ({ [KeyType in keyof StorefrontMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontMutations[RawGqlString]["variables"], Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>>)[KeyType]; } : { readonly [variable: string]: unknown; }>>)?] : [StorefrontCommonExtraParams & ClientVariables<StorefrontMutations, RawGqlString, AutoAddedVariableNames, "variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof StorefrontMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontMutations[RawGqlString]["variables"], Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>>)]: ({ [KeyType in keyof StorefrontMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontMutations[RawGqlString]["variables"], Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>>)[KeyType]; } : { readonly [variable: string]: unknown; }, Record<"variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof StorefrontMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontMutations[RawGqlString]["variables"], Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>>)]: ({ [KeyType in keyof StorefrontMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>]: StorefrontMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<StorefrontMutations[RawGqlString]["variables"], Extract<keyof StorefrontMutations[RawGqlString]["variables"], AutoAddedVariableNames>>>)[KeyType]; } : { readonly [variable: string]: unknown; }>>]) => Promise<ClientReturn<StorefrontMutations, RawGqlString, OverrideReturnType> & StorefrontError>
  ```

* cache

  ```ts
  Cache
  ```

* CacheNone

  ```ts
  () => NoStoreStrategy
  ```

* CacheLong

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

* CacheShort

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

* CacheCustom

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

* generateCacheControlHeader

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

* getPublicTokenHeaders

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

* getPrivateTokenHeaders

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

* getShopifyDomain

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

* getApiUrl

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

* isApiError

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

* i18n

  ```ts
  TI18n
  ```

### StorefrontQueries

Maps all the queries found in the project to variables and return types.



### AutoAddedVariableNames

```ts
'country' | 'language'
```

### StorefrontCommonExtraParams

* headers

  ```ts
  HeadersInit
  ```

* storefrontApiVersion

  ```ts
  string
  ```

* displayName

  ```ts
  string
  ```

### StorefrontQueryOptions

```ts
StorefrontCommonExtraParams & {
  query: string;
  mutation?: never;
  cache?: CachingStrategy;
}
```

### 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

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

  ```ts
  string
  ```

* maxAge

  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).

  ```ts
  number
  ```

* staleWhileRevalidate

  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).

  ```ts
  number
  ```

* sMaxAge

  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).

  ```ts
  number
  ```

* staleIfError

  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).

  ```ts
  number
  ```

### StorefrontError

* errors

  ```ts
  StorefrontApiErrors
  ```

### StorefrontApiErrors

```ts
JsonGraphQLError[] | undefined
```

### StorefrontMutations

Maps all the mutations found in the project to variables and return types.



### NoStoreStrategy

* mode

  ```ts
  string
  ```

### AllCacheOptions

Override options for a cache strategy.

* mode

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

  ```ts
  string
  ```

* maxAge

  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).

  ```ts
  number
  ```

* staleWhileRevalidate

  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).

  ```ts
  number
  ```

* sMaxAge

  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).

  ```ts
  number
  ```

* staleIfError

  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).

  ```ts
  number
  ```

## Returns

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

* **addLines**

  **CartLinesAddFunction**

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

* **create**

  **CartCreateFunction**

  Creates a new cart.

* **deleteMetafield**

  **CartMetafieldDeleteFunction**

  Removes a custom field (metafield) from the cart.

* **get**

  **CartGetFunction**

  Retrieves the cart information.

* **getCartId**

  **() => string**

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

* **removeLines**

  **CartLinesRemoveFunction**

  Removes items from the cart.

* **setCartId**

  **(cartId: string) => Headers**

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

* **setMetafields**

  **CartMetafieldsSetFunction**

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

* **updateAttributes**

  **CartAttributesUpdateFunction**

  Updates additional information (attributes) in the cart.

* **updateBuyerIdentity**

  **CartBuyerIdentityUpdateFunction**

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

* **updateDiscountCodes**

  **CartDiscountCodesUpdateFunction**

  Updates discount codes in the cart.

* **updateLines**

  **CartLinesUpdateFunction**

  Updates items in the cart.

* **updateNote**

  **CartNoteUpdateFunction**

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

* **updateSelectedDeliveryOption**

  **CartSelectedDeliveryOptionsUpdateFunction**

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

### CartLinesAddFunction

* lines

  ```ts
  CartLineInput[]
  ```

* optionalParams

  ```ts
  CartOptionalInput
  ```

Promise\<CartQueryDataReturn>

```ts
Promise<CartQueryDataReturn>
```

### CartLineInput



### CartOptionalInput

* cartId

  The cart id.

  ```ts
  string
  ```

* country

  The country code.

  ```ts
  CountryCode
  ```

* language

  The language code.

  ```ts
  LanguageCode
  ```

### CartQueryDataReturn

```ts
CartQueryData & {
  errors?: StorefrontApiErrors;
}
```

### CartQueryData

* cart

  ```ts
  Cart
  ```

* userErrors

  ```ts
  CartUserError[] | MetafieldsSetUserError[] | MetafieldDeleteUserError[]
  ```

### Cart



### CartUserError



### MetafieldsSetUserError



### MetafieldDeleteUserError



### CartCreateFunction

* input

  ```ts
  CartInput
  ```

* optionalParams

  ```ts
  CartOptionalInput
  ```

Promise\<CartQueryDataReturn>

```ts
Promise<CartQueryDataReturn>
```

### CartInput



### CartMetafieldDeleteFunction

* key

  ```ts
  string
  ```

* optionalParams

  ```ts
  CartOptionalInput
  ```

Promise\<CartQueryDataReturn>

```ts
Promise<CartQueryDataReturn>
```

### CartGetFunction

* cartInput

  ```ts
  CartGetProps
  ```

Promise\<CartReturn | null>

```ts
Promise<CartReturn | null>
```

### CartGetProps

* cartId

  The cart ID.

  ```ts
  string
  ```

* country

  The country code.

  ```ts
  CountryCode
  ```

* language

  The language code.

  ```ts
  LanguageCode
  ```

* numCartLines

  The number of cart lines to be returned.

  ```ts
  number
  ```

### CartReturn

```ts
Cart & {
  errors?: StorefrontApiErrors;
}
```

### CartLinesRemoveFunction

* lineIds

  ```ts
  string[]
  ```

* optionalParams

  ```ts
  CartOptionalInput
  ```

Promise\<CartQueryDataReturn>

```ts
Promise<CartQueryDataReturn>
```

### CartMetafieldsSetFunction

* metafields

  ```ts
  MetafieldWithoutOwnerId[]
  ```

* optionalParams

  ```ts
  CartOptionalInput
  ```

Promise\<CartQueryDataReturn>

```ts
Promise<CartQueryDataReturn>
```

### MetafieldWithoutOwnerId



### CartAttributesUpdateFunction

* attributes

  ```ts
  AttributeInput[]
  ```

* optionalParams

  ```ts
  CartOptionalInput
  ```

Promise\<CartQueryDataReturn>

```ts
Promise<CartQueryDataReturn>
```

### AttributeInput



### CartBuyerIdentityUpdateFunction

* buyerIdentity

  ```ts
  CartBuyerIdentityInput
  ```

* optionalParams

  ```ts
  CartOptionalInput
  ```

Promise\<CartQueryDataReturn>

```ts
Promise<CartQueryDataReturn>
```

### CartBuyerIdentityInput



### CartDiscountCodesUpdateFunction

* discountCodes

  ```ts
  string[]
  ```

* optionalParams

  ```ts
  CartOptionalInput
  ```

Promise\<CartQueryDataReturn>

```ts
Promise<CartQueryDataReturn>
```

### CartLinesUpdateFunction

* lines

  ```ts
  CartLineUpdateInput[]
  ```

* optionalParams

  ```ts
  CartOptionalInput
  ```

Promise\<CartQueryDataReturn>

```ts
Promise<CartQueryDataReturn>
```

### CartLineUpdateInput



### CartNoteUpdateFunction

* note

  ```ts
  string
  ```

* optionalParams

  ```ts
  CartOptionalInput
  ```

Promise\<CartQueryDataReturn>

```ts
Promise<CartQueryDataReturn>
```

### CartSelectedDeliveryOptionsUpdateFunction

* selectedDeliveryOptions

  ```ts
  CartSelectedDeliveryOptionInput[]
  ```

* optionalParams

  ```ts
  CartOptionalInput
  ```

Promise\<CartQueryDataReturn>

```ts
Promise<CartQueryDataReturn>
```

### CartSelectedDeliveryOptionInput



Examples

### Examples

* #### server.(js|ts)

  ##### Description

  This is the default example

  ##### JavaScript

  ```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);
    },
  };
  ```

  ##### TypeScript

  ```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);
    },
  };
  ```

* #### Example

  ##### Description

  Use \`cartQueryFragment\` and \`cartMutateFragment\` to change the cart data the queries will return.

  ##### JavaScript

  ```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
          }
        }
      }
    }
  `;
  ```

* #### Example

  ##### Description

  Define or override methods in your cart handler instance. Note that for addLines, updateDiscountCodes, updateBuyerIdentity, updateNote, updateAttributes, and setMetafields, if you override any of these methods, a new cart will not be created unless you implement the cart creation logic in your overriding method.

  ##### JavaScript

  ```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.addLines

  ##### Description

  Add items to the cart. If the cart does not exist, a new cart will be created.

  ##### JavaScript

  ```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: []
  // }
  ```

* #### cart.create

  ##### Description

  Create a new cart.

  ##### JavaScript

  ```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: []
    // }
  }
  ```

* #### cart.deleteMetafield

  ##### Description

  Delete extra information (metafield) from the cart.

  ##### JavaScript

  ```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
      }

    }
  `;
  ```

* #### cart.get

  ##### Description

  Retrieve the cart information.

  ##### JavaScript

  ```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'
    });
  }
  ```

* #### cart.getCartId

  ##### Description

  Get the unique identifier of the cart.

  ##### JavaScript

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

* #### cart.removeLines

  ##### Description

  Remove items from the cart.

  ##### JavaScript

  ```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: []
    // }
  }
  ```

* #### cart.setCartId

  ##### Description

  Set the unique identifier of the cart.

  ##### JavaScript

  ```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);
  }
  ```

* #### cart.setMetafields

  ##### Description

  Add extra information (metafields) to the cart. If the cart does not exist, a new cart will be created.

  ##### JavaScript

  ```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
      }

    }
  `;
  ```

* #### cart.updateAttributes

  ##### Description

  Update additional information (attributes) in the cart. If the cart does not exist, a new cart will be created.

  ##### JavaScript

  ```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: []
    // }
  }
  ```

* #### cart.updateBuyerIdentity

  ##### Description

  Update the buyer’s information in the cart. If the cart does not exist, a new cart will be created.

  ##### JavaScript

  ```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: []
    // }
  }
  ```

* #### cart.updateDiscountCodes

  ##### Description

  Update discount codes in the cart.

  ##### JavaScript

  ```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: []
    // }
  }
  ```

* #### cart.updateLines

  ##### Description

  Update items in the cart.

  ##### JavaScript

  ```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: []
    // }
  }
  ```

* #### cart.updateNote

  ##### Description

  Update the note in the cart. If the cart does not exist, a new cart will be created.

  ##### JavaScript

  ```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: []
    // }
  }
  ```

* #### cart.updateSelectedDeliveryOptions

  ##### Description

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

  ##### JavaScript

  ```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: []
    // }
  }
  ```
