# 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, executionContext: ExecutionContext, ): Promise { 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` - Headers: Headers A function that sets the cart ID. ### storefront value: `Storefront` - Storefront: { /** The function to run a query on Storefront API. */ query: ( query: RawGqlString, ...options: RawGqlString extends keyof StorefrontQueries // Do we have any generated query types? ? IsOptionalVariables extends true ? [StorefrontQuerySecondParam?] // Using codegen, query has no variables : [StorefrontQuerySecondParam] // Using codegen, query needs variables : [StorefrontQuerySecondParam?] // No codegen, variables always optional ) => Promise< RawGqlString extends keyof StorefrontQueries // Do we have any generated query types? ? StorefrontQueries[RawGqlString]['return'] // Using codegen, return type is known : OverrideReturnType // No codegen, let user specify return type >; /** The function to run a mutation on Storefront API. */ mutate: ( mutation: RawGqlString, ...options: RawGqlString extends keyof StorefrontMutations // Do we have any generated mutation types? ? IsOptionalVariables extends true ? [StorefrontMutateSecondParam?] // Using codegen, mutation has no variables : [StorefrontMutateSecondParam] // Using codegen, mutation needs variables : [StorefrontMutateSecondParam?] // No codegen, variables always optional ) => Promise< RawGqlString extends keyof StorefrontMutations // Do we have any generated mutation types? ? StorefrontMutations[RawGqlString]['return'] // Using codegen, return type is known : OverrideReturnType // No codegen, let user specify return type >; /** The cache instance passed in from the `createStorefrontClient` argument. */ cache?: Cache; /** Re-export of [`CacheNone`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachenone). */ CacheNone: typeof CacheNone; /** Re-export of [`CacheLong`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachelong). */ CacheLong: typeof CacheLong; /** Re-export of [`CacheShort`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cacheshort). */ CacheShort: typeof CacheShort; /** Re-export of [`CacheCustom`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachecustom). */ CacheCustom: typeof CacheCustom; /** Re-export of [`generateCacheControlHeader`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/generatecachecontrolheader). */ generateCacheControlHeader: typeof generateCacheControlHeader; /** 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. */ getPublicTokenHeaders: ReturnType< typeof createStorefrontUtilities >['getPublicTokenHeaders']; /** 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.*/ getPrivateTokenHeaders: ReturnType< typeof createStorefrontUtilities >['getPrivateTokenHeaders']; /** 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. */ getShopifyDomain: ReturnType< typeof createStorefrontUtilities >['getShopifyDomain']; /** 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.*/ getApiUrl: ReturnType< typeof createStorefrontUtilities >['getStorefrontApiUrl']; /** Determines if the error is resulted from a Storefront API call. */ isApiError: (error: any) => boolean; /** The `i18n` object passed in from the `createStorefrontClient` argument. */ i18n: TI18n; } 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: `(query: RawGqlString, ...options: RawGqlString extends never ? IsOptionalVariables extends true ? [StorefrontQuerySecondParam?] : [StorefrontQuerySecondParam] : [StorefrontQuerySecondParam?]) => Promise` - Storefront: { /** The function to run a query on Storefront API. */ query: ( query: RawGqlString, ...options: RawGqlString extends keyof StorefrontQueries // Do we have any generated query types? ? IsOptionalVariables extends true ? [StorefrontQuerySecondParam?] // Using codegen, query has no variables : [StorefrontQuerySecondParam] // Using codegen, query needs variables : [StorefrontQuerySecondParam?] // No codegen, variables always optional ) => Promise< RawGqlString extends keyof StorefrontQueries // Do we have any generated query types? ? StorefrontQueries[RawGqlString]['return'] // Using codegen, return type is known : OverrideReturnType // No codegen, let user specify return type >; /** The function to run a mutation on Storefront API. */ mutate: ( mutation: RawGqlString, ...options: RawGqlString extends keyof StorefrontMutations // Do we have any generated mutation types? ? IsOptionalVariables extends true ? [StorefrontMutateSecondParam?] // Using codegen, mutation has no variables : [StorefrontMutateSecondParam] // Using codegen, mutation needs variables : [StorefrontMutateSecondParam?] // No codegen, variables always optional ) => Promise< RawGqlString extends keyof StorefrontMutations // Do we have any generated mutation types? ? StorefrontMutations[RawGqlString]['return'] // Using codegen, return type is known : OverrideReturnType // No codegen, let user specify return type >; /** The cache instance passed in from the `createStorefrontClient` argument. */ cache?: Cache; /** Re-export of [`CacheNone`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachenone). */ CacheNone: typeof CacheNone; /** Re-export of [`CacheLong`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachelong). */ CacheLong: typeof CacheLong; /** Re-export of [`CacheShort`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cacheshort). */ CacheShort: typeof CacheShort; /** Re-export of [`CacheCustom`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachecustom). */ CacheCustom: typeof CacheCustom; /** Re-export of [`generateCacheControlHeader`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/generatecachecontrolheader). */ generateCacheControlHeader: typeof generateCacheControlHeader; /** 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. */ getPublicTokenHeaders: ReturnType< typeof createStorefrontUtilities >['getPublicTokenHeaders']; /** 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.*/ getPrivateTokenHeaders: ReturnType< typeof createStorefrontUtilities >['getPrivateTokenHeaders']; /** 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. */ getShopifyDomain: ReturnType< typeof createStorefrontUtilities >['getShopifyDomain']; /** 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.*/ getApiUrl: ReturnType< typeof createStorefrontUtilities >['getStorefrontApiUrl']; /** Determines if the error is resulted from a Storefront API call. */ isApiError: (error: any) => boolean; /** The `i18n` object passed in from the `createStorefrontClient` argument. */ i18n: TI18n; } - IsOptionalVariables: Omit< OperationTypeValue['variables'], AutoAddedVariableNames > extends EmptyVariables ? true // No need to pass variables : GenericVariables extends OperationTypeValue['variables'] ? true // We don't know what variables are needed : false - StorefrontQueries: export interface StorefrontQueries { // Example of how a generated query type looks like: // '#graphql query q1 {...}': {return: Q1Query; variables: Q1QueryVariables}; } - StorefrontQuerySecondParam: (RawGqlString extends keyof StorefrontQueries ? StorefrontCommonOptions : StorefrontCommonOptions) & {cache?: CachingStrategy} The function to run a query on Storefront API. ### mutate value: `(mutation: RawGqlString, ...options: RawGqlString extends never ? IsOptionalVariables extends true ? [StorefrontMutateSecondParam?] : [StorefrontMutateSecondParam] : [StorefrontCommonOptions<{ readonly [variable: string]: unknown; }>?]) => Promise` - Storefront: { /** The function to run a query on Storefront API. */ query: ( query: RawGqlString, ...options: RawGqlString extends keyof StorefrontQueries // Do we have any generated query types? ? IsOptionalVariables extends true ? [StorefrontQuerySecondParam?] // Using codegen, query has no variables : [StorefrontQuerySecondParam] // Using codegen, query needs variables : [StorefrontQuerySecondParam?] // No codegen, variables always optional ) => Promise< RawGqlString extends keyof StorefrontQueries // Do we have any generated query types? ? StorefrontQueries[RawGqlString]['return'] // Using codegen, return type is known : OverrideReturnType // No codegen, let user specify return type >; /** The function to run a mutation on Storefront API. */ mutate: ( mutation: RawGqlString, ...options: RawGqlString extends keyof StorefrontMutations // Do we have any generated mutation types? ? IsOptionalVariables extends true ? [StorefrontMutateSecondParam?] // Using codegen, mutation has no variables : [StorefrontMutateSecondParam] // Using codegen, mutation needs variables : [StorefrontMutateSecondParam?] // No codegen, variables always optional ) => Promise< RawGqlString extends keyof StorefrontMutations // Do we have any generated mutation types? ? StorefrontMutations[RawGqlString]['return'] // Using codegen, return type is known : OverrideReturnType // No codegen, let user specify return type >; /** The cache instance passed in from the `createStorefrontClient` argument. */ cache?: Cache; /** Re-export of [`CacheNone`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachenone). */ CacheNone: typeof CacheNone; /** Re-export of [`CacheLong`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachelong). */ CacheLong: typeof CacheLong; /** Re-export of [`CacheShort`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cacheshort). */ CacheShort: typeof CacheShort; /** Re-export of [`CacheCustom`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachecustom). */ CacheCustom: typeof CacheCustom; /** Re-export of [`generateCacheControlHeader`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/generatecachecontrolheader). */ generateCacheControlHeader: typeof generateCacheControlHeader; /** 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. */ getPublicTokenHeaders: ReturnType< typeof createStorefrontUtilities >['getPublicTokenHeaders']; /** 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.*/ getPrivateTokenHeaders: ReturnType< typeof createStorefrontUtilities >['getPrivateTokenHeaders']; /** 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. */ getShopifyDomain: ReturnType< typeof createStorefrontUtilities >['getShopifyDomain']; /** 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.*/ getApiUrl: ReturnType< typeof createStorefrontUtilities >['getStorefrontApiUrl']; /** Determines if the error is resulted from a Storefront API call. */ isApiError: (error: any) => boolean; /** The `i18n` object passed in from the `createStorefrontClient` argument. */ i18n: TI18n; } - IsOptionalVariables: Omit< OperationTypeValue['variables'], AutoAddedVariableNames > extends EmptyVariables ? true // No need to pass variables : GenericVariables extends OperationTypeValue['variables'] ? true // We don't know what variables are needed : false - StorefrontCommonOptions: { headers?: HeadersInit; storefrontApiVersion?: string; } & (IsOptionalVariables<{variables: Variables}> extends true ? {variables?: Variables} : {variables: Variables}) - StorefrontMutations: export interface StorefrontMutations { // Example of how a generated mutation type looks like: // '#graphql mutation m1 {...}': {return: M1Mutation; variables: M1MutationVariables}; } - StorefrontMutateSecondParam: RawGqlString extends keyof StorefrontMutations ? StorefrontCommonOptions : StorefrontCommonOptions The function to run a mutation on Storefront API. ### cache value: `Cache` The cache instance passed in from the `createStorefrontClient` argument. ### CacheNone value: `() => NoStoreStrategy` - NoStoreStrategy: { mode: string; } Re-export of [`CacheNone`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachenone). ### CacheLong value: `(overrideOptions?: AllCacheOptions) => AllCacheOptions` - AllCacheOptions: export interface AllCacheOptions { /** * The caching mode, generally `public`, `private`, or `no-store`. */ mode?: string; /** * 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). */ maxAge?: 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). */ staleWhileRevalidate?: 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). */ sMaxAge?: 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). */ staleIfError?: number; } Re-export of [`CacheLong`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachelong). ### CacheShort value: `(overrideOptions?: AllCacheOptions) => AllCacheOptions` - AllCacheOptions: export interface AllCacheOptions { /** * The caching mode, generally `public`, `private`, or `no-store`. */ mode?: string; /** * 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). */ maxAge?: 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). */ staleWhileRevalidate?: 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). */ sMaxAge?: 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). */ staleIfError?: number; } Re-export of [`CacheShort`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cacheshort). ### CacheCustom value: `(overrideOptions: AllCacheOptions) => AllCacheOptions` - AllCacheOptions: export interface AllCacheOptions { /** * The caching mode, generally `public`, `private`, or `no-store`. */ mode?: string; /** * 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). */ maxAge?: 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). */ staleWhileRevalidate?: 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). */ sMaxAge?: 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). */ staleIfError?: number; } Re-export of [`CacheCustom`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachecustom). ### generateCacheControlHeader value: `(cacheOptions: AllCacheOptions) => string` - AllCacheOptions: export interface AllCacheOptions { /** * The caching mode, generally `public`, `private`, or `no-store`. */ mode?: string; /** * 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). */ maxAge?: 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). */ staleWhileRevalidate?: 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). */ sMaxAge?: 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). */ staleIfError?: number; } Re-export of [`generateCacheControlHeader`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/generatecachecontrolheader). ### getPublicTokenHeaders value: `(props?: Partial> & Pick) => Record` - Storefront: { /** The function to run a query on Storefront API. */ query: ( query: RawGqlString, ...options: RawGqlString extends keyof StorefrontQueries // Do we have any generated query types? ? IsOptionalVariables extends true ? [StorefrontQuerySecondParam?] // Using codegen, query has no variables : [StorefrontQuerySecondParam] // Using codegen, query needs variables : [StorefrontQuerySecondParam?] // No codegen, variables always optional ) => Promise< RawGqlString extends keyof StorefrontQueries // Do we have any generated query types? ? StorefrontQueries[RawGqlString]['return'] // Using codegen, return type is known : OverrideReturnType // No codegen, let user specify return type >; /** The function to run a mutation on Storefront API. */ mutate: ( mutation: RawGqlString, ...options: RawGqlString extends keyof StorefrontMutations // Do we have any generated mutation types? ? IsOptionalVariables extends true ? [StorefrontMutateSecondParam?] // Using codegen, mutation has no variables : [StorefrontMutateSecondParam] // Using codegen, mutation needs variables : [StorefrontMutateSecondParam?] // No codegen, variables always optional ) => Promise< RawGqlString extends keyof StorefrontMutations // Do we have any generated mutation types? ? StorefrontMutations[RawGqlString]['return'] // Using codegen, return type is known : OverrideReturnType // No codegen, let user specify return type >; /** The cache instance passed in from the `createStorefrontClient` argument. */ cache?: Cache; /** Re-export of [`CacheNone`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachenone). */ CacheNone: typeof CacheNone; /** Re-export of [`CacheLong`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachelong). */ CacheLong: typeof CacheLong; /** Re-export of [`CacheShort`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cacheshort). */ CacheShort: typeof CacheShort; /** Re-export of [`CacheCustom`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachecustom). */ CacheCustom: typeof CacheCustom; /** Re-export of [`generateCacheControlHeader`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/generatecachecontrolheader). */ generateCacheControlHeader: typeof generateCacheControlHeader; /** 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. */ getPublicTokenHeaders: ReturnType< typeof createStorefrontUtilities >['getPublicTokenHeaders']; /** 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.*/ getPrivateTokenHeaders: ReturnType< typeof createStorefrontUtilities >['getPrivateTokenHeaders']; /** 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. */ getShopifyDomain: ReturnType< typeof createStorefrontUtilities >['getShopifyDomain']; /** 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.*/ getApiUrl: ReturnType< typeof createStorefrontUtilities >['getStorefrontApiUrl']; /** Determines if the error is resulted from a Storefront API call. */ isApiError: (error: any) => boolean; /** The `i18n` object passed in from the `createStorefrontClient` argument. */ i18n: TI18n; } 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 & { buyerIp?: string; }) => Record` - Storefront: { /** The function to run a query on Storefront API. */ query: ( query: RawGqlString, ...options: RawGqlString extends keyof StorefrontQueries // Do we have any generated query types? ? IsOptionalVariables extends true ? [StorefrontQuerySecondParam?] // Using codegen, query has no variables : [StorefrontQuerySecondParam] // Using codegen, query needs variables : [StorefrontQuerySecondParam?] // No codegen, variables always optional ) => Promise< RawGqlString extends keyof StorefrontQueries // Do we have any generated query types? ? StorefrontQueries[RawGqlString]['return'] // Using codegen, return type is known : OverrideReturnType // No codegen, let user specify return type >; /** The function to run a mutation on Storefront API. */ mutate: ( mutation: RawGqlString, ...options: RawGqlString extends keyof StorefrontMutations // Do we have any generated mutation types? ? IsOptionalVariables extends true ? [StorefrontMutateSecondParam?] // Using codegen, mutation has no variables : [StorefrontMutateSecondParam] // Using codegen, mutation needs variables : [StorefrontMutateSecondParam?] // No codegen, variables always optional ) => Promise< RawGqlString extends keyof StorefrontMutations // Do we have any generated mutation types? ? StorefrontMutations[RawGqlString]['return'] // Using codegen, return type is known : OverrideReturnType // No codegen, let user specify return type >; /** The cache instance passed in from the `createStorefrontClient` argument. */ cache?: Cache; /** Re-export of [`CacheNone`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachenone). */ CacheNone: typeof CacheNone; /** Re-export of [`CacheLong`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachelong). */ CacheLong: typeof CacheLong; /** Re-export of [`CacheShort`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cacheshort). */ CacheShort: typeof CacheShort; /** Re-export of [`CacheCustom`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachecustom). */ CacheCustom: typeof CacheCustom; /** Re-export of [`generateCacheControlHeader`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/generatecachecontrolheader). */ generateCacheControlHeader: typeof generateCacheControlHeader; /** 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. */ getPublicTokenHeaders: ReturnType< typeof createStorefrontUtilities >['getPublicTokenHeaders']; /** 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.*/ getPrivateTokenHeaders: ReturnType< typeof createStorefrontUtilities >['getPrivateTokenHeaders']; /** 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. */ getShopifyDomain: ReturnType< typeof createStorefrontUtilities >['getShopifyDomain']; /** 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.*/ getApiUrl: ReturnType< typeof createStorefrontUtilities >['getStorefrontApiUrl']; /** Determines if the error is resulted from a Storefront API call. */ isApiError: (error: any) => boolean; /** The `i18n` object passed in from the `createStorefrontClient` argument. */ i18n: TI18n; } 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>) => string` - Storefront: { /** The function to run a query on Storefront API. */ query: ( query: RawGqlString, ...options: RawGqlString extends keyof StorefrontQueries // Do we have any generated query types? ? IsOptionalVariables extends true ? [StorefrontQuerySecondParam?] // Using codegen, query has no variables : [StorefrontQuerySecondParam] // Using codegen, query needs variables : [StorefrontQuerySecondParam?] // No codegen, variables always optional ) => Promise< RawGqlString extends keyof StorefrontQueries // Do we have any generated query types? ? StorefrontQueries[RawGqlString]['return'] // Using codegen, return type is known : OverrideReturnType // No codegen, let user specify return type >; /** The function to run a mutation on Storefront API. */ mutate: ( mutation: RawGqlString, ...options: RawGqlString extends keyof StorefrontMutations // Do we have any generated mutation types? ? IsOptionalVariables extends true ? [StorefrontMutateSecondParam?] // Using codegen, mutation has no variables : [StorefrontMutateSecondParam] // Using codegen, mutation needs variables : [StorefrontMutateSecondParam?] // No codegen, variables always optional ) => Promise< RawGqlString extends keyof StorefrontMutations // Do we have any generated mutation types? ? StorefrontMutations[RawGqlString]['return'] // Using codegen, return type is known : OverrideReturnType // No codegen, let user specify return type >; /** The cache instance passed in from the `createStorefrontClient` argument. */ cache?: Cache; /** Re-export of [`CacheNone`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachenone). */ CacheNone: typeof CacheNone; /** Re-export of [`CacheLong`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachelong). */ CacheLong: typeof CacheLong; /** Re-export of [`CacheShort`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cacheshort). */ CacheShort: typeof CacheShort; /** Re-export of [`CacheCustom`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachecustom). */ CacheCustom: typeof CacheCustom; /** Re-export of [`generateCacheControlHeader`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/generatecachecontrolheader). */ generateCacheControlHeader: typeof generateCacheControlHeader; /** 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. */ getPublicTokenHeaders: ReturnType< typeof createStorefrontUtilities >['getPublicTokenHeaders']; /** 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.*/ getPrivateTokenHeaders: ReturnType< typeof createStorefrontUtilities >['getPrivateTokenHeaders']; /** 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. */ getShopifyDomain: ReturnType< typeof createStorefrontUtilities >['getShopifyDomain']; /** 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.*/ getApiUrl: ReturnType< typeof createStorefrontUtilities >['getStorefrontApiUrl']; /** Determines if the error is resulted from a Storefront API call. */ isApiError: (error: any) => boolean; /** The `i18n` object passed in from the `createStorefrontClient` argument. */ i18n: TI18n; } 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>) => string` - Storefront: { /** The function to run a query on Storefront API. */ query: ( query: RawGqlString, ...options: RawGqlString extends keyof StorefrontQueries // Do we have any generated query types? ? IsOptionalVariables extends true ? [StorefrontQuerySecondParam?] // Using codegen, query has no variables : [StorefrontQuerySecondParam] // Using codegen, query needs variables : [StorefrontQuerySecondParam?] // No codegen, variables always optional ) => Promise< RawGqlString extends keyof StorefrontQueries // Do we have any generated query types? ? StorefrontQueries[RawGqlString]['return'] // Using codegen, return type is known : OverrideReturnType // No codegen, let user specify return type >; /** The function to run a mutation on Storefront API. */ mutate: ( mutation: RawGqlString, ...options: RawGqlString extends keyof StorefrontMutations // Do we have any generated mutation types? ? IsOptionalVariables extends true ? [StorefrontMutateSecondParam?] // Using codegen, mutation has no variables : [StorefrontMutateSecondParam] // Using codegen, mutation needs variables : [StorefrontMutateSecondParam?] // No codegen, variables always optional ) => Promise< RawGqlString extends keyof StorefrontMutations // Do we have any generated mutation types? ? StorefrontMutations[RawGqlString]['return'] // Using codegen, return type is known : OverrideReturnType // No codegen, let user specify return type >; /** The cache instance passed in from the `createStorefrontClient` argument. */ cache?: Cache; /** Re-export of [`CacheNone`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachenone). */ CacheNone: typeof CacheNone; /** Re-export of [`CacheLong`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachelong). */ CacheLong: typeof CacheLong; /** Re-export of [`CacheShort`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cacheshort). */ CacheShort: typeof CacheShort; /** Re-export of [`CacheCustom`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/cachecustom). */ CacheCustom: typeof CacheCustom; /** Re-export of [`generateCacheControlHeader`](https://shopify.dev/docs/api/hydrogen/2023-10/utilities/generatecachecontrolheader). */ generateCacheControlHeader: typeof generateCacheControlHeader; /** 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. */ getPublicTokenHeaders: ReturnType< typeof createStorefrontUtilities >['getPublicTokenHeaders']; /** 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.*/ getPrivateTokenHeaders: ReturnType< typeof createStorefrontUtilities >['getPrivateTokenHeaders']; /** 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. */ getShopifyDomain: ReturnType< typeof createStorefrontUtilities >['getShopifyDomain']; /** 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.*/ getApiUrl: ReturnType< typeof createStorefrontUtilities >['getStorefrontApiUrl']; /** Determines if the error is resulted from a Storefront API call. */ isApiError: (error: any) => boolean; /** The `i18n` object passed in from the `createStorefrontClient` argument. */ i18n: TI18n; } 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 Use `cartQueryFragment` and `cartMutateFragment` to change the cart data the queries will return.```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 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.```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 Add items to the cart. If the cart does not exist, a new cart will be created.```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: [] // } ``` Create a new cart.```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: [] // } } ``` Delete extra information (metafield) from the cart.```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 } } `; ``` Retrieve the cart information.```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' }); } ``` Get the unique identifier of the cart.```js export async function loader({context}) { // Usage context.cart.getCartId(); // 'gid://shopify/Cart/123' } ``` Remove items from the cart.```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: [] // } } ``` Set the unique identifier of the cart.```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); } ``` Add extra information (metafields) to the cart. If the cart does not exist, a new cart will be created.```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 } } `; ``` Update additional information (attributes) in the cart. If the cart does not exist, a new cart will be created.```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: [] // } } ``` Update the buyer’s information in the cart. If the cart does not exist, a new cart will be created.```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: [] // } } ``` Update discount codes in the cart.```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: [] // } } ``` Update items in the cart.```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: [] // } } ``` Update the note in the cart. If the cart does not exist, a new cart will be created.```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: [] // } } ``` Update the selected delivery options in the cart. Only available for carts associated with a customer access token.```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` - CartLinesAddFunction: export type CartLinesAddFunction = ( lines: CartLineInput[], optionalParams?: CartOptionalInput, ) => Promise; - Cart: Cart Adds items to the cart. If the cart doesn't exist, a new one will be created. ### create value: `CartCreateFunction` - Cart: Cart - CartCreateFunction: export type CartCreateFunction = ( input: CartInput, optionalParams?: CartOptionalInput, ) => Promise; Creates a new cart. ### deleteMetafield value: `CartMetafieldDeleteFunction` - Cart: Cart - CartMetafieldDeleteFunction: export type CartMetafieldDeleteFunction = ( key: Scalars['String']['input'], optionalParams?: CartOptionalInput, ) => Promise; Removes a custom field (metafield) from the cart. ### get value: `CartGetFunction` - Cart: Cart - CartGetFunction: export type CartGetFunction = ( cartInput?: CartGetProps, ) => Promise; 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` - Cart: Cart - CartLinesRemoveFunction: export type CartLinesRemoveFunction = ( lineIds: string[], optionalParams?: CartOptionalInput, ) => Promise; Removes items from the cart. ### setCartId value: `(cartId: string) => Headers` - Headers: Headers Sets the unique identifier of the cart. By default, it sets the ID in the header cookie. ### setMetafields value: `CartMetafieldsSetFunction` - Cart: Cart - CartMetafieldsSetFunction: export type CartMetafieldsSetFunction = ( metafields: MetafieldWithoutOwnerId[], optionalParams?: CartOptionalInput, ) => Promise; Adds extra information (metafields) to the cart. If the cart doesn't exist, a new one will be created. ### updateAttributes value: `CartAttributesUpdateFunction` - Cart: Cart - CartAttributesUpdateFunction: export type CartAttributesUpdateFunction = ( attributes: AttributeInput[], optionalParams?: CartOptionalInput, ) => Promise; Updates additional information (attributes) in the cart. ### updateBuyerIdentity value: `CartBuyerIdentityUpdateFunction` - Cart: Cart - CartBuyerIdentityUpdateFunction: export type CartBuyerIdentityUpdateFunction = ( buyerIdentity: CartBuyerIdentityInput, optionalParams?: CartOptionalInput, ) => Promise; Updates the buyer's information in the cart. If the cart doesn't exist, a new one will be created. ### updateDiscountCodes value: `CartDiscountCodesUpdateFunction` - Cart: Cart - CartDiscountCodesUpdateFunction: export type CartDiscountCodesUpdateFunction = ( discountCodes: string[], optionalParams?: CartOptionalInput, ) => Promise; Updates discount codes in the cart. ### updateLines value: `CartLinesUpdateFunction` - Cart: Cart - CartLinesUpdateFunction: export type CartLinesUpdateFunction = ( lines: CartLineUpdateInput[], optionalParams?: CartOptionalInput, ) => Promise; Updates items in the cart. ### updateNote value: `CartNoteUpdateFunction` - Cart: Cart - CartNoteUpdateFunction: export type CartNoteUpdateFunction = ( note: string, optionalParams?: CartOptionalInput, ) => Promise; Updates the note in the cart. If the cart doesn't exist, a new one will be created. ### updateSelectedDeliveryOption value: `CartSelectedDeliveryOptionsUpdateFunction` - Cart: Cart - CartSelectedDeliveryOptionsUpdateFunction: export type CartSelectedDeliveryOptionsUpdateFunction = ( selectedDeliveryOptions: CartSelectedDeliveryOptionInput[], optionalParams?: CartOptionalInput, ) => Promise; Updates the selected delivery options in the cart. Only available for carts associated with a customer access token. ### CartLinesAddFunction #### Returns: Promise #### Params: - lines: CartLineInput[] - optionalParams: CartOptionalInput export type CartLinesAddFunction = ( lines: CartLineInput[], optionalParams?: CartOptionalInput, ) => Promise; ### CartOptionalInput ### cartId value: `string` The cart id. ### country value: `CountryCode` The country code. ### language value: `LanguageCode` The language code. ### CartQueryData ### cart value: `Cart` - Cart: Cart ### errors value: `CartUserError[] | MetafieldsSetUserError[] | MetafieldDeleteUserError[]` - Cart: Cart - CartUserError: CartUserError - MetafieldsSetUserError: MetafieldsSetUserError - MetafieldDeleteUserError: MetafieldDeleteUserError ### CartCreateFunction #### Returns: Promise #### Params: - input: CartInput - optionalParams: CartOptionalInput export type CartCreateFunction = ( input: CartInput, optionalParams?: CartOptionalInput, ) => Promise; ### CartMetafieldDeleteFunction #### Returns: Promise #### Params: - key: string - optionalParams: CartOptionalInput export type CartMetafieldDeleteFunction = ( key: Scalars['String']['input'], optionalParams?: CartOptionalInput, ) => Promise; ### CartGetFunction #### Returns: Promise #### Params: - cartInput: CartGetProps export type CartGetFunction = ( cartInput?: CartGetProps, ) => Promise; ### 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 #### Params: - lineIds: string[] - optionalParams: CartOptionalInput export type CartLinesRemoveFunction = ( lineIds: string[], optionalParams?: CartOptionalInput, ) => Promise; ### CartMetafieldsSetFunction #### Returns: Promise #### Params: - metafields: MetafieldWithoutOwnerId[] - optionalParams: CartOptionalInput export type CartMetafieldsSetFunction = ( metafields: MetafieldWithoutOwnerId[], optionalParams?: CartOptionalInput, ) => Promise; ### CartAttributesUpdateFunction #### Returns: Promise #### Params: - attributes: AttributeInput[] - optionalParams: CartOptionalInput export type CartAttributesUpdateFunction = ( attributes: AttributeInput[], optionalParams?: CartOptionalInput, ) => Promise; ### CartBuyerIdentityUpdateFunction #### Returns: Promise #### Params: - buyerIdentity: CartBuyerIdentityInput - optionalParams: CartOptionalInput export type CartBuyerIdentityUpdateFunction = ( buyerIdentity: CartBuyerIdentityInput, optionalParams?: CartOptionalInput, ) => Promise; ### CartDiscountCodesUpdateFunction #### Returns: Promise #### Params: - discountCodes: string[] - optionalParams: CartOptionalInput export type CartDiscountCodesUpdateFunction = ( discountCodes: string[], optionalParams?: CartOptionalInput, ) => Promise; ### CartLinesUpdateFunction #### Returns: Promise #### Params: - lines: CartLineUpdateInput[] - optionalParams: CartOptionalInput export type CartLinesUpdateFunction = ( lines: CartLineUpdateInput[], optionalParams?: CartOptionalInput, ) => Promise; ### CartNoteUpdateFunction #### Returns: Promise #### Params: - note: string - optionalParams: CartOptionalInput export type CartNoteUpdateFunction = ( note: string, optionalParams?: CartOptionalInput, ) => Promise; ### CartSelectedDeliveryOptionsUpdateFunction #### Returns: Promise #### Params: - selectedDeliveryOptions: CartSelectedDeliveryOptionInput[] - optionalParams: CartOptionalInput export type CartSelectedDeliveryOptionsUpdateFunction = ( selectedDeliveryOptions: CartSelectedDeliveryOptionInput[], optionalParams?: CartOptionalInput, ) => Promise; ## Examples Creates an API that can be used to interact with the cart. ### Cart fragments Use `cartQueryFragment` and `cartMutateFragment` to change the cart data the queries will return.```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 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.```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 Add items to the cart. If the cart does not exist, a new cart will be created.```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: [] // } ``` Create a new cart.```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: [] // } } ``` Delete extra information (metafield) from the cart.```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 } } `; ``` Retrieve the cart information.```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' }); } ``` Get the unique identifier of the cart.```js export async function loader({context}) { // Usage context.cart.getCartId(); // 'gid://shopify/Cart/123' } ``` Remove items from the cart.```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: [] // } } ``` Set the unique identifier of the cart.```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); } ``` Add extra information (metafields) to the cart. If the cart does not exist, a new cart will be created.```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 } } `; ``` Update additional information (attributes) in the cart. If the cart does not exist, a new cart will be created.```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: [] // } } ``` Update the buyer’s information in the cart. If the cart does not exist, a new cart will be created.```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: [] // } } ``` Update discount codes in the cart.```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: [] // } } ``` Update items in the cart.```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: [] // } } ``` Update the note in the cart. If the cart does not exist, a new cart will be created.```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: [] // } } ``` Update the selected delivery options in the cart. Only available for carts associated with a customer access token.```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: [] // } } ``` ## Examples Creates an API that can be used to interact with the cart. ### Cart fragments Use `cartQueryFragment` and `cartMutateFragment` to change the cart data the queries will return.```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 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.```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 Add items to the cart. If the cart does not exist, a new cart will be created.```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: [] // } ``` Create a new cart.```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: [] // } } ``` Delete extra information (metafield) from the cart.```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 } } `; ``` Retrieve the cart information.```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' }); } ``` Get the unique identifier of the cart.```js export async function loader({context}) { // Usage context.cart.getCartId(); // 'gid://shopify/Cart/123' } ``` Remove items from the cart.```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: [] // } } ``` Set the unique identifier of the cart.```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); } ``` Add extra information (metafields) to the cart. If the cart does not exist, a new cart will be created.```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 } } `; ``` Update additional information (attributes) in the cart. If the cart does not exist, a new cart will be created.```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: [] // } } ``` Update the buyer’s information in the cart. If the cart does not exist, a new cart will be created.```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: [] // } } ``` Update discount codes in the cart.```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: [] // } } ``` Update items in the cart.```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: [] // } } ``` Update the note in the cart. If the cart does not exist, a new cart will be created.```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: [] // } } ``` Update the selected delivery options in the cart. Only available for carts associated with a customer access token.```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: [] // } } ```