Cart server handlers
The cart server handlers serve the /api/cart route, which loads and updates the customer's cart through the Storefront API. Use these functions to register the cart route, load the cart in server loaders, parse cart requests in custom routes, and set the cart cookie.
Import createCartServerHandlers, parseCartRequest, getCart, getCartId, createCartCookie, and CartDataFromQuery from @shopify/hydrogen.
Pass the handlers to handleShopifyRoutes to serve the cart route before your framework's router runs.
Anchor to Cart routeCart route
Creates the handlers for the route, which loads and changes the customer's cart.
The handlers read the cart ID from the cart cookie and set the cookie when they create a cart. A JSON request gets a JSON response, and a form submission gets a 303 redirect to the referring page.
Pass to connect carts to the logged-in customer. The handlers then need and in their context.
- Anchor to optionsoptionsoptionsCreateCartServerHandlersOptions<AnyStorefrontQueryString>CreateCartServerHandlersOptions<AnyStorefrontQueryString>
A custom cart fragment and the customer session.
The GET and POST handlers to register with
.
CreateCartServerHandlersOptions
Options for creating cart server handlers.
CartServerHandlersOptionsWithCustomerSession<TCartFragment> | CartServerHandlersOptionsWithoutCustomerSession<TCartFragment>CartServerHandlersOptionsWithCustomerSession
Options for cart server handlers that attach the logged-in customer to new carts.
- customerSession
The customer session from `createCustomerSession`. Pass the session to attach the logged-in customer to new carts.
CartCustomerSession - fragment
A cart fragment that adds fields to the cart in every cart query and mutation response. Name the fragment `CartFragment` on the `Cart` type. `createCartServerHandlers` throws for any other fragment name or type.
TCartFragment
CartCustomerSession
The customer session from `createCustomerSession`. The cart handlers read the customer's login state and access token from the session.
- getAccessToken
Returns the customer's stored access token, or `undefined` when the token is missing or expired. The method never refreshes the token or writes to the session. Call `getOrRefreshAccessToken()` to refresh an expired token.
(sessionManager: ReadonlyCustomerSessionManager, requestContext: ShopifyRequestContext) => Promise<string> - getOrRefreshAccessToken
Returns a usable access token for the customer. When the stored token is missing or expired, the session gets new tokens from Shopify and writes them to your session storage. Call the method only where you commit the session to the response. Returns `undefined` when the customer has no refresh token, or when a temporary refresh failure keeps the session for a retry. When Shopify rejects the refresh token with a `400` or `401` status, the session clears the stored tokens and returns `undefined`. Refresh failures never throw.
(sessionManager: ShopifyRouteSessionManager, requestContext: ShopifyRequestContext, options?: RequestOriginOptions) => Promise<string> - handleOAuthCallback
Completes sign-in from Shopify's OAuth callback request, saves the customer's tokens to your session storage, and returns the path to send the customer to. Commit the session to the response after the call. The method throws `CustomerAccountOAuthError` when sign-in fails a check, and `CustomerAccountApiError` when the token request times out. After a failure, the customer needs to start sign-in again.
(sessionManager: ShopifyRouteSessionManager, requestContext: ShopifyRequestContext, request: Request) => Promise<string> - isLoggedIn
Returns `true` when the customer has a usable access token or a refresh token. The method never refreshes tokens. Use the result for UI state, such as an account link. Gate Customer Account API data on an access token from `getOrRefreshAccessToken()`.
(sessionManager: ReadonlyCustomerSessionManager, requestContext: ShopifyRequestContext) => Promise<boolean> - logout
Clears the customer's session data and returns the URL to send the customer to. Commit the session to the response after the call. When the session has an ID token, the URL points to Shopify's logout endpoint with the post-logout URL attached. Without an ID token, the method returns the post-logout URL.
(sessionManager: ShopifyRouteSessionManager, requestContext: ShopifyRequestContext, options?: LogoutOptions) => Promise<string> - prepareLoginUrl
Starts customer sign-in and returns the URL of Shopify's login page. Commit the session to the response, then redirect the customer to the URL. The customer has 10 minutes to finish signing in. After that, the OAuth callback fails with the `missing_pending_login` code.
(sessionManager: ShopifyRouteSessionManager, requestContext: ShopifyRequestContext, options: PrepareLoginUrlOptions) => Promise<string>
ReadonlyCustomerSessionManager
The session storage that `isLoggedIn()` and `getAccessToken()` read.
- getSessionItem
Returns the session value for a key. The customer session keeps its data under the `customerAccount` key.
(key: string) => unknown
ShopifyRequestContext
The context for one request. Pass the context to Hydrogen's API clients and route handlers for that request.
ShopifyRequestContextBase & {
i18n: NormalizedI18nConfig<I18n>;
}ShopifyRequestContextBase
The fields and methods on every request context.
- __hydrogenShopifyRequestContextBrand
A type-only marker. Create request contexts only with `createShopifyRequestContext`.
never - applyResponseHeaders
Adds the headers that a Hydrogen storefront needs to the final response. Call the method on each response that your app builds. Responses from `handleShopifyRoutes` and `handleShopifyRedirects` already carry these headers. Append your committed session headers before you call the method. The method makes any response that sets a cookie private and uncacheable. The method also sets the `powered-by` header, makes responses that hold customer data private and uncacheable, and adds eligible Shopify cookies only to non-document responses for methods other than `GET` and `HEAD`.
(headers: Headers) => void - applyStorefrontRequestHeaders
Adds the Hydrogen SDK headers and the customer's cookie, privacy, and origin headers to a Storefront API request. The Storefront API client and the API proxies call the method for you.
(headers: Headers) => void - buyerIp
The customer's trusted IP address. Private Storefront API clients require it.
string - captureSubrequestHeaders
Saves the cookies from the first Storefront API response that sets cookies. The Storefront API client calls the method for you, and `applyResponseHeaders()` can add the cookies to your response.
(headers: Headers) => void - consumeStorefrontResponseHeaders
Saves the cookies from a proxied Storefront API response and removes the `set-cookie` header from that response. The API proxies in `handleShopifyRoutes` call the method for you.
(headers: Headers) => void - cookie
The incoming request's `Cookie` header. Hydrogen forwards the header to the Storefront API.
string - getForwardedRequestHeaders
Returns the incoming request's headers with Shopify's request headers added. Pass the headers when you forward the request to a proxy or another origin.
() => Headers - i18n
The request's language, country, and path prefix. The path prefix starts with `/` and has no trailing slash, or is an empty string when you don't set one.
NormalizedI18nConfig - markResponseAsPersonalized
Marks the final response as private and uncacheable because the response holds customer data. The Customer Account API client and the customer session call the method for you.
(reason: string) => void - markResponseAsSessionEstablishing
Lets the final response set Shopify cookies before the customer has a Shopify session, and marks the response as private and uncacheable. The UCP MCP proxy calls the method for you.
(reason: string) => void - requestGroupId
The ID that groups this request's Shopify API calls. Hydrogen reads the ID from the request headers or generates one.
string - signal
The incoming request's abort signal. Hydrogen's API clients stop their requests when the signal aborts.
AbortSignal - storefrontOrigin
The origin of the incoming request's URL. Hydrogen forwards the origin to the Storefront API.
string - url
The incoming request's URL.
string
Headers
NormalizedI18nConfig
The request's locale, with a path prefix that starts with `/` or is an empty string.
Omit<I18n, "pathPrefix"> & {
pathPrefix: string;
}ShopifyRouteSessionManager
The session storage that route handlers and the customer session read and write. Implement the methods with your app's session.
- commit
Saves session changes and returns the headers, such as a cookie, to add to the response.
() => Awaitable<void | HeadersInit> - getSessionItem
Returns the session value stored under a key.
(key: string) => unknown - getSessionOrigin
Returns your storefront's HTTPS origin. Customer account sign-in builds its OAuth redirect URL from the origin.
() => Awaitable<string> - removeSessionItem
Deletes the session value stored under a key.
(key: string) => Awaitable<void> - setSessionItem
Stores a value in the session under a key.
(key: string, value: unknown) => Awaitable<void>
Awaitable
A value or a promise for that value.
T | Promise<T>RequestOriginOptions
The storefront origin for a token refresh or logout.
- origin
Your storefront's HTTPS origin. Defaults to the origin that the session manager returns. A non-HTTPS origin throws.
string
LogoutOptions
Options for logging the customer out.
- origin
Your storefront's HTTPS origin. Defaults to the origin that the session manager returns. A non-HTTPS origin throws.
string - postLogoutRedirectUri
The URL to send the customer to after logout. A relative URL resolves against the origin. Defaults to the origin, and a cross-origin URL falls back to the origin.
string
PrepareLoginUrlOptions
Options for building a Shopify OAuth login URL.
- acrValues
The authentication context class to request, sent as the `acr_values` search param.
string - countryCode
The customer's country, sent as the `region_country` search param.
string - locale
The language for Shopify's login page, sent as the `locale` search param.
string - loginHint
A value that prefills Shopify's login page, such as the customer's email address, sent as the `login_hint` search param.
string - loginHintMode
How Shopify's login page uses the login hint, such as `submit`, sent as the `login_hint_mode` search param. Hydrogen sends the value only with `loginHint`.
string - origin
Your storefront's origin for the OAuth redirect URL. Defaults to the origin that the session manager returns. The origin must use HTTPS, including on localhost. Use a public HTTPS tunnel for local sign-in.
string - returnTo
The same-origin path or URL to send the customer to after sign-in, such as `/account/orders`. Defaults to `/account`. Cross-origin values and paths over 2,048 bytes fall back to the default.
string
CartServerHandlersOptionsWithoutCustomerSession
Options for cart server handlers without a customer session.
- customerSession
Leave the option out to create carts without a customer.
undefined - fragment
A cart fragment that adds fields to the cart in every cart query and mutation response. Name the fragment `CartFragment` on the `Cart` type. `createCartServerHandlers` throws for any other fragment name or type.
TCartFragment
AnyStorefrontQueryString
Any `gql` document, whatever its result and variables types. Use the type to accept any Storefront API document.
string & StorefrontQueryMetadataStorefrontQueryMetadata
Type-only properties that mark a string as a `gql` document.
- __hydrogenQueryBrand
Marks a string that `gql` returns. The property exists only in types.
true - __hydrogenQuerySource
The document's query text, which TypeScript reads to infer types. The property exists only in types.
Source
CartServerHandlers
The cart route handlers that `createCartServerHandlers` returns. Register the handlers with `handleShopifyRoutes` to serve the `/api/cart` route that the cart store calls.
- __@cartServerHandlersCartQuery@23708
The cart query document that the handlers run.
TCartQuery | undefined - get
Returns the current cart. The handler reads the cart ID from the request's `cartId` search parameter or `cart` cookie. Without a request, the handler reads the cart ID from the Storefront API client's request context. GraphQL errors return a `null` cart with the errors in the response body. The handler throws when the Storefront API request fails.
CartGetHandler<TCart> - post
Runs the cart change that the request describes and returns the updated cart. An add without a cart creates a cart and sets the `cart` cookie. Other changes without a cart return a `missing_cart` error for a JSON request and a redirect for a form submission. When a JSON body names a cart other than the cookie's cart, the handler leaves the cookie unchanged. The handler throws GraphQL and network errors from the mutation.
CartPostHandler
CartGetHandler
CartPostHandler
CartServerHandlersWithCustomerSession
The cart route handlers that `createCartServerHandlers` returns when you pass `customerSession`. The handlers connect carts to the logged-in customer. Pass `sessionManager` and `requestContext` in each handler's context. A handler throws when it reads the customer session and either value is missing.
- __@cartBuyerIdentitySync@22178
Connects the cart to the customer when the customer logs in, and disconnects the cart when the customer logs out. Create the cart server handlers with `customerSession`, then pass the handlers to `createCustomerAccountServerHandlers` through the `cartServerHandlers` option. The customer account handlers then update the cart for you.
CartBuyerIdentitySync - __@cartServerHandlersCartQuery@23708
The cart query document that the handlers run.
TCartQuery | undefined - get
Returns the cart like the GET handler in `CartServerHandlers`. For a logged-in customer, the handler adds `logged_in=true` to the checkout URL.
CartGetHandler<TCart, CartGetHandlerContext & CartCustomerSessionReadContext> - post
Runs cart changes like the POST handler in `CartServerHandlers`. When an add creates a cart for a logged-in customer, the handler attaches the customer to the new cart. When the handler refreshes the customer's access token and the mutation then fails, the handler returns a `cart_mutation_failed` error with status `500`.
CartPostHandler<CartPostHandlerContext & CartCustomerSessionWriteContext>
CartBuyerIdentitySync
Connects the cart to the customer when the customer logs in, and disconnects the cart when the customer logs out. Create the cart server handlers with `customerSession`, then pass the handlers to `createCustomerAccountServerHandlers` through the `cartServerHandlers` option. The customer account handlers then update the cart for you.
- expiredCartCookie
A `Set-Cookie` value that clears the `cart` cookie. The customer account handlers send the value when they can't detach the customer from the cart.
string - updateBuyerIdentity
Attaches the customer to the cart in the request's `cart` cookie, or detaches the customer when the token is `null`.
(context: CartBuyerIdentitySyncContext, customerAccessToken: string) => Promise<void>
CartBuyerIdentitySyncContext
The request with the `cart` cookie and the Storefront API client that updates the cart.
- request
The incoming request. The `cart` cookie on the request identifies the cart.
Request - storefrontClient
The Storefront API client that updates the cart's buyer identity.
StorefrontClient
StorefrontClient
A Storefront API client. Call `graphql()` with a document to run a query or mutation and get a typed result.
- apiUrl
The Storefront API GraphQL endpoint that the client calls.
string - graphql
Runs a Storefront API query or mutation and returns a typed result. Pass a `gql` document or a plain query string. When the operation declares `$country` or `$language`, the client sets the variable from the request context and overrides any value you pass. The method throws an error when a query passes a `cache` strategy and the client has no cache, or when the strategy uses `private` mode. A catch block for `StorefrontApiError` doesn't catch this configuration error. To cache customer-specific data, use `createRunWithCache` with a key unique to the customer.
<const Doc extends DocLike | string>(doc: Doc, ...options: GqlRestParam<ResolveDoc<Doc>, Extra>) => Promise<StorefrontGraphqlResult<ResolveDoc<Doc>>> - i18n
The country and language that the client sends for `$country` and `$language` variables.
RequestContext["i18n"] - requestContext
The request context that you passed to `createStorefrontClient`.
RequestContext - storefrontId
The storefront ID from the client options.
string - storeUrl
Your store's URL with its protocol, such as `https://my-store.myshopify.com`.
string - type
The client type that you passed to `createStorefrontClient`.
Type
DocLike
A document that the client's GraphQL method accepts, from `gql` or from `gql`.tada.
TadaDocumentNode<any, any> | AnyStorefrontQueryStringGqlRestParam
The options argument of a GraphQL call. Pass the options argument when the document declares a required variable. You can leave the options argument out when every variable is optional, or when the only required variables are `$country` and `$language`, which the client fills.
HasNoRequiredKeys<MergedOptions<Doc, GraphqlExtraOptionsForDoc<Doc, Extra>>> extends true
? [options?: MergedOptions<Doc, GraphqlExtraOptionsForDoc<Doc, Extra>>]
: [options: MergedOptions<Doc, GraphqlExtraOptionsForDoc<Doc, Extra>>]HasNoRequiredKeys
Resolves to `true` when an object type has no required keys.
Record<string, never> extends T ? true : falseMergedOptions
The options for a GraphQL call. The call needs `variables` only when the document declares a required variable.
Extra & StorefrontGraphqlOptions & (HasNoRequiredKeys<UserVariables<Doc>> extends true
? { variables?: UserVariables<Doc> }
: { variables: UserVariables<Doc> })StorefrontGraphqlOptions
Options that every Storefront API GraphQL call accepts.
- signal
Cancels the request when the signal aborts. The request context's signal and the client timeout also cancel the request. The signal doesn't cancel a stale-while-revalidate refresh.
AbortSignal
UserVariables
The variables that you pass for a document, without `country` and `language`. The client fills both from the request context.
VariablesOfDoc
The variables that a Customer Account document declares.
Doc extends CustomerAccountDocument<unknown, infer Variables, string> ? Variables : neverCustomerAccountDocument
A Customer Account API query or mutation that `gql` from `@shopify/hydrogen/customer-account` returns. TypeScript infers the result and variables types from the document's GraphQL source. Create documents only with the Customer Account `gql` function. The client throws a `TypeError` for any other object.
DocumentDecoration<Result, Variables> & {
readonly [CUSTOMER_ACCOUNT_DOCUMENT]: true;
readonly source: Source;
}GraphqlExtraOptionsForDoc
Offers the `cache` option only for documents that TypeScript recognizes as queries.
OperationKindOfDoc<Doc> extends "query" ? Extra : Omit<Extra, "cache">OperationKindOfDoc
The operation kind of a document, such as `query`. Resolves to `unknown` when the query text isn't a string literal type.
[SourceText<Doc>] extends [never]
? "unknown"
: string extends SourceText<Doc>
? "unknown"
: InferOperationKind<SourceText<Doc>>SourceText
The query text of a document as a string literal type. A plain string resolves to itself.
[SourceOf<Doc>] extends [never]
? Doc extends string
? Doc
: never
: SourceOf<Doc>InferOperationKind
The operation kind of a query string, such as `query`. Resolves to `unknown` unless the query text has exactly one operation.
parseDocument<T> extends infer Doc
? [Doc] extends [never]
? "unknown"
: OperationKindType<Doc>
: "unknown"OperationKindType
ResolveDoc
The typed document for a GraphQL call. Hydrogen infers the types when you pass a plain query string.
D extends DocLike ? D : D extends string ? InferredDoc<D> : neverInferredDoc
StorefrontGraphqlResult
The result of a GraphQL call, with the data, any GraphQL errors, and the response headers. Check `errors` before you read `data`. Without errors, `data` holds the full result, typed from your document. With errors, `data` is `null` after a request error or after a failed non-null field at the root. Otherwise, `data` holds a partial result, and `null` replaces each failed field or its nearest nullable parent.
{ data: ResultOfDoc<Doc>; errors?: undefined; headers: Headers } | { data: ResultOfDoc<Doc> | null; errors: GraphQLFormattedError[]; headers: Headers }ResultOfDoc
The result type of a `gql` document or a `gql`.tada document node.
Doc extends StorefrontQueryString<infer Result, infer _Variables, string>
? Result
: Doc extends TadaDocumentNode<any, any>
? TadaResultOf<Doc>
: neverStorefrontQueryString
GraphQLFormattedError
A GraphQL error from the Storefront API. The result of a GraphQL call lists GraphQL errors in its `errors` field.
- extensions
Extra details that the Storefront API adds to the error.
Record<string, unknown> - locations
The lines and columns in the query where the error occurs.
ReadonlyArray<{ line: number; column: number }> - message
The error message.
string - path
The path to the response field that failed.
ReadonlyArray<string | number>
CartGetHandlerContext
The context that you pass to the cart GET handler.
- request
The incoming request. Omit the request to read the cart ID from the Storefront API client's request context.
Request - storefrontClient
The Storefront API client that runs the cart query.
StorefrontClient
CartCustomerSessionReadContext
The extra context that the GET handler needs when you create the handlers with `customerSession`.
- requestContext
The current request's context, for checking the customer's login state.
ShopifyRequestContext - sessionManager
The session storage that holds the customer's tokens.
ReadonlyCustomerSessionManager
CartPostHandlerContext
The context that you pass to the cart POST handler.
- request
The cart request, with a JSON, URL-encoded form, or multipart form body.
Request - storefrontClient
The Storefront API client that runs the cart mutation.
StorefrontClient
CartCustomerSessionWriteContext
The extra context that the POST handler needs when you create the handlers with `customerSession`.
- requestContext
The current request's context, for reading or refreshing the customer's access token.
ShopifyRequestContext - sessionManager
The session storage that holds the customer's tokens. After a token refresh, the handler commits the session and adds its `Set-Cookie` headers to the response.
WritableCustomerSessionManager
WritableCustomerSessionManager
The session storage that sign-in, the OAuth callback, token refresh, and logout write to. Commit the session to the response after you call `prepareLoginUrl()`, `handleOAuthCallback()`, `getOrRefreshAccessToken()`, or `logout()`.
- commit
Saves session changes and returns the headers, such as a cookie, to add to the response.
() => Awaitable<void | HeadersInit> - getSessionItem
Returns the session value stored under a key.
(key: string) => unknown - getSessionOrigin
Returns your storefront's HTTPS origin. Customer account sign-in builds its OAuth redirect URL from the origin.
() => Awaitable<string> - removeSessionItem
Deletes the session value stored under a key.
(key: string) => Awaitable<void> - setSessionItem
Stores a value in the session under a key.
(key: string, value: unknown) => Awaitable<void>
Anchor to cartgetresultCartGetResult
The JSON result that the cart GET handler returns. The handler sets private cache headers that keep CDNs and shared caches from storing the cart.
- Anchor to datadatadataTDataTDatarequiredrequired
The value that Hydrogen serializes as the response body.
- Anchor to typetypetype'json''json'requiredrequired
Set to
jsonfor a JSON response.- Anchor to headersheadersheadersHeadersInitHeadersInit
Extra headers for the response. Hydrogen sets
content-typetoand overrides any value you pass.
Anchor to cartgetdataCartGetData
The response body that the cart GET handler returns.
- Anchor to cartcartcartTCart | nullTCart | nullrequiredrequired
The cart, or
nullwhen the request has no cart ID, the cart doesn't exist, or the cart query returns GraphQL errors.- Anchor to errorserrorserrorsArray<{ message: string }>Array<{ message: string }>
GraphQL errors from the cart query. The handler also logs the errors on the server.
CartPostResult is the route result that the cart POST handler returns. Check type to tell the results apart:
jsonanswers a JSON request with the same fields asCartGetResult. The result'sdataholds the mutation'scart,userErrors, andwarnings.redirectanswers a form submission with a303redirect to the referring page.errorholds aCartErrorwith a code that identifies the failure.
Anchor to shopifyrouteredirectresultShopifyRouteRedirectResult
A route handler result that Hydrogen sends as a redirect response.
- Anchor to locationlocationlocationstringstringrequiredrequired
The redirect target. Hydrogen resolves a relative path against the request's origin.
- Anchor to typetypetype'redirect''redirect'requiredrequired
Set to
redirectfor a redirect response.- Anchor to headersheadersheadersHeadersInitHeadersInit
Extra headers for the redirect response.
- Anchor to statusstatusstatusShopifyRedirectStatusShopifyRedirectStatus
The HTTP redirect status. Defaults to
303.
ShopifyRedirectStatus
The HTTP status codes a route handler can use for a redirect.
301 | 302 | 303 | 307 | 308Anchor to shopifyrouteerrorresultShopifyRouteErrorResult
A route handler result that Hydrogen sends as a JSON error response.
- Anchor to errorerrorerrorTErrorTErrorrequiredrequired
The error that Hydrogen serializes as the response body's
errorfield.- Anchor to typetypetype'error''error'requiredrequired
Set to
errorfor an error response.- Anchor to headersheadersheadersHeadersInitHeadersInit
Extra headers for the error response. Hydrogen sets
content-typetoand overrides any value you pass.- Anchor to statusstatusstatusnumbernumber
The HTTP status for the error response. Defaults to
400.
Anchor to carterrorCartError
An error that the cart POST handler returns, with a code that identifies the failure.
- Anchor to codecodecodeCartErrorCodeCartErrorCoderequiredrequired
The code that identifies the failure.
- Anchor to messagemessagemessagestringstringrequiredrequired
A human-readable error message.
CartErrorCode
Error codes that the cart POST handler returns. The handler returns `invalid_cart_request` when it can't parse a JSON request, and `missing_cart` when a JSON request changes the cart but has no cart ID. With `customerSession`, the handler returns `cart_mutation_failed` when a mutation fails after the handler refreshes the customer's access token.
"invalid_cart_request" | "missing_cart" | "cart_mutation_failed"TypeScript
Examples
Description
Create the handlers once at module scope and pass the handlers to `handleShopifyRoutes` before your framework's router runs.
TypeScript
import { createCartServerHandlers, handleShopifyRoutes, type ShopifyRouteHandlerContext, } from "@shopify/hydrogen"; export const cartHandlers = createCartServerHandlers(); export function handleRequest( context: ShopifyRouteHandlerContext, next: () => Promise<Response>, ) { const shopifyRoute = handleShopifyRoutes({ ...context, handlers: [cartHandlers], }); if (shopifyRoute) return shopifyRoute; return next(); }Description
Add your own cart fields to every cart query and mutation with a `CartFragment`.
TypeScript
import { createCartServerHandlers, gql } from "@shopify/hydrogen"; const cartFragment = gql(` fragment CartFragment on Cart { lines(first: 250) { nodes { merchandise { ... on ProductVariant { availableForSale } } } } } `); export const cartHandlers = createCartServerHandlers({ fragment: cartFragment, });Description
Call `cartHandlers.get()` directly and return a promise of its data for streaming.
TypeScript
import { createCartServerHandlers, type StorefrontClient } from "@shopify/hydrogen"; const cartHandlers = createCartServerHandlers(); export async function loader(storefrontClient: StorefrontClient) { const cartData = cartHandlers.get({ storefrontClient }).then(({ data }) => data); return { cartData }; }
Anchor to Cart request helpersCart request helpers
Reads the cart change from a cart request body. Use the function in a custom cart route.
The function accepts , , and requests. A JSON request can replace every discount code, and a form submission applies or removes one code.
A form submission always returns a null cart ID. Read the cart ID for a form submission with .
The function reads the request body, and you can't read the body again afterward. The function throws when the request has an unsupported content type, an unknown intent, or a missing required field, and when a JSON body combines more than one of lines, , attributes, and note.
Anchor to parseCartRequest-parametersParameters
- Anchor to requestrequestrequestRequestRequestrequiredrequired
The incoming cart request.
The cart change and, for a JSON body, the cart ID.
ParsedCartRequest
The cart change and the cart ID that `parseCartRequest` reads from the request body.
- action
A cart change that `parseCartRequest` reads from a JSON or form request. The `intent` field names the change and the Storefront API mutation that applies the change: - `add` adds new lines with `cartLinesAdd`, or creates a cart with `cartCreate` when none exists. - `update` changes quantity, merchandise, or attributes on existing lines with `cartLinesUpdate`. - `remove` removes lines by ID with `cartLinesRemove`. - `discount-update` replaces all discount codes with `cartDiscountCodesUpdate`. - `discount-apply` adds one discount code. The handler reads the current codes, then writes the new list with `cartDiscountCodesUpdate`. - `discount-remove` removes one discount code with the same read-then-write approach. - `attributes-update` sets cart-level attributes with `cartAttributesUpdate`. - `note-update` sets the cart note with `cartNoteUpdate`.
CartAction - cartId
The cart GID from a JSON body, or `null` for a form submission or a JSON body without a cart ID. The function adds the `gid://shopify/Cart/` prefix to a bare cart token.
string | null
CartAction
Fetches a cart by ID from the Storefront API.
Pass a custom cart query to get a cart with that query's fields. Declare an $id variable in the query. The function passes the cart ID as the query's only variable.
When the cart ID is null, the function returns a null cart without a network request. The function throws when the Storefront API request fails.
Anchor to getCart-parametersParameters
- Anchor to cartIdcart
Idcart Id stringstringrequiredrequired The ID of the cart to fetch, or
nullto skip the request.- Anchor to storefrontstorefrontstorefrontStorefrontCartClientStorefrontCartClientrequiredrequired
The Storefront API client that runs the cart query.
- Anchor to cartQuerycart
Querycart Query AnyStorefrontQueryStringAnyStorefrontQueryString A cart query document that replaces the default cart query.
Anchor to getCart-returnsReturns
The cart or
null, any GraphQL errors, and the Storefront API response headers.
StorefrontCartClient
The Storefront API client that runs the cart query.
- graphql
Runs a Storefront API query or mutation and returns a typed result. Pass a `gql` document or a plain query string. When the operation declares `$country` or `$language`, the client sets the variable from the request context and overrides any value you pass. The method throws an error when a query passes a `cache` strategy and the client has no cache, or when the strategy uses `private` mode. A catch block for `StorefrontApiError` doesn't catch this configuration error. To cache customer-specific data, use `createRunWithCache` with a key unique to the customer.
<const Doc extends DocLike | string>(doc: Doc, ...options: GqlRestParam<ResolveDoc<Doc>, {}>) => Promise<StorefrontGraphqlResult<ResolveDoc<Doc>>>
CartResult
The cart that `getCart` returns, with any GraphQL errors and the Storefront API response headers.
- cart
The cart, or `null` when the cart ID is missing, the cart doesn't exist, or the query fails.
TCart | null - errors
GraphQL errors from the cart query.
Array<{ message: string }> - headers
The Storefront API response headers, such as cache directives. The headers are empty when `getCart` skips the request.
Headers
CartData
The customer's cart, in the shape that the Storefront API returns. Cart costs come only from the server. Extra fields from your custom cart fragment appear unchanged.
- [key: string]
unknown - attributes
Cart-level custom attributes.
Attribute[] - checkoutUrl
The Shopify checkout URL. The URL can change when the customer logs in or out, or changes tracking consent.
string | null - cost
The cart's subtotal, total, and checkout charge.
CartCost - discountCodes
Discount codes applied to the cart, with their applicability.
DiscountCode[] - id
The cart's Storefront API GID, or `null` when no cart exists yet.
string | null - lines
The cart's line items.
CartLineConnection - note
Customer-supplied cart note, or `null` or empty when unset.
string | null - totalQuantity
Sum of all line quantities.
number - updatedAt
The cart's last update time in ISO 8601 format. Absent until the first server response.
string
Attribute
A key-value pair attached to the cart or to an individual cart line.
- key
The attribute name. Look up the attribute's errors with this name.
string - value
The attribute value.
string | null
CartCost
The cart's costs from the Storefront API.
- checkoutChargeAmount
Estimated amount due at checkout, excluding deferred payments. Equals the subtotal when no deferred payments exist.
Money - subtotalAmount
The amount, before taxes and cart-level discounts, for the customer to pay.
Money - totalAmount
Final amount the customer pays at checkout.
Money
Money
A monetary value from the Storefront API.
- amount
The decimal amount as a string, such as `29.99`.
string - currencyCode
The ISO 4217 currency code, such as `USD`.
string
DiscountCode
A discount code applied to the cart.
- applicable
Whether the code applies to the cart's current contents. A new code reads `false` until the server responds.
boolean - code
The discount code text. Look up the code's pending state and errors with this value.
string
CartLineConnection
The cart's line items in the Storefront API connection shape.
- [key: string]
unknown - nodes
The cart lines that the cart query returns.
CartLine[]
CartLine
A single line item in the cart. Each line holds a product variant at a quantity. A line can carry custom attributes, a selling plan allocation for a subscription, or line components for a bundle.
- attributes
Custom key-value attributes attached to the line.
Attribute[] - cost
Per-line cost breakdown from the Storefront API.
CartLineCost - id
The cart line's Storefront API GID. Look up the line's pending state and errors with this ID.
string - lineComponents
Nested child lines when this line is a bundle parent.
CartLine[] - merchandise
The product variant on the line.
CartLineMerchandise - parentRelationship
The parent line's ID when this line is a bundle component.
{ parent: { id: string } } | null - quantity
Number of units of this merchandise in the cart.
number - sellingPlanAllocation
Subscription selling plan allocation, or `null` for one-time purchases.
{ sellingPlan: { id: string } } | null
CartLineCost
A cart line's costs from the Storefront API.
- amountPerQuantity
Unit price for a single quantity of this line.
Money - compareAtAmountPerQuantity
Original compare-at unit price, or `null` when no comparison exists.
Money | null - subtotalAmount
Line subtotal before line-level discounts.
Money - totalAmount
Line total after all applicable discounts.
Money
CartLineMerchandise
The product variant on a cart line.
- [key: string]
unknown - id
Storefront API GID of the product variant.
string - image
The variant image that the cart query selects.
{ id?: string | null; url: string; altText?: string | null; width?: number | null; height?: number | null; [key: string]: unknown; } | null - product
The product that the variant belongs to.
{ [key: string]: unknown; title: string; handle?: string; } - quantityAvailable
Units available for sale. When your cart fragment selects the field, the store caps the quantity of a `set` submission at this number.
number | null - selectedOptions
The variant's selected options as name and value pairs.
Array<{ name: string; value: string }> - title
The variant title, such as `"Small / Black"`.
string
Reads the cart ID from a request.
The function checks the search parameter first, then the cart cookie. The function returns a search parameter value unchanged and adds the prefix to a cookie value.
Anchor to getCartId-parametersParameters
- Anchor to inputinputinputCartIdSourceCartIdSourcerequiredrequired
The request or request context that carries the cart ID.
Anchor to getCartId-returnsReturns
The cart ID, or
nullwhen neither the search parameter nor the cookie has one.
CartIdSource
A request, or a request context with a `Cookie` header and a URL.
Request | Pick<ShopifyRequestContext, "cookie" | "url">TypeScript
Examples
Description
Parse a cart request and fall back to `getCartId` for the cart ID. This example returns a `400` response when parsing fails and a `404` response when no cart exists.
TypeScript
import { cartQueries, getCartId, parseCartRequest, type StorefrontClient } from "@shopify/hydrogen"; export async function handleCartPost(request: Request, storefrontClient: StorefrontClient) { const parsed = await parseCartRequest(request).catch(() => null); if (!parsed) return Response.json({ error: "Invalid cart request" }, { status: 400 }); const cartId = parsed.cartId ?? getCartId(request); if (!cartId) return Response.json({ error: "No cart exists" }, { status: 404 }); const { action } = parsed; switch (action.intent) { case "remove": { const { data } = await storefrontClient.graphql(cartQueries.cartLinesRemove, { variables: { cartId, lineIds: action.lineIds }, }); return Response.json(data); } case "note-update": { const { data } = await storefrontClient.graphql(cartQueries.cartNoteUpdate, { variables: { cartId, note: action.note }, }); return Response.json(data); } default: return Response.json({ error: `Unsupported intent ${action.intent}` }, { status: 400 }); } }
Creates the Set-Cookie header value that stores the cart ID in the cart cookie.
The cookie holds the cart token without the prefix and expires after 14 days. The cookie sets Path=/ and , and leaves out and Secure. Append the value to the response headers to keep the response's other cookies.
Anchor to createCartCookie-parametersParameters
- stringstringrequiredrequired
The cart GID or cart token to store.
Anchor to createCartCookie-returnsReturnsstringstring
The header value that sets the
cartcookie.
TypeScript
Examples
Description
Create a cart with a discount code and attach the cookie to a `303` redirect.
TypeScript
import { cartQueries, createCartCookie, type StorefrontClient } from "@shopify/hydrogen"; export async function createCartWithDiscount(code: string, storefrontClient: StorefrontClient) { const { data } = await storefrontClient.graphql(cartQueries.cartCreate, { variables: { input: { discountCodes: [code] } }, }); const cart = data?.cartCreate?.cart; const headers = new Headers({ location: "/" }); if (cart) headers.append("set-cookie", createCartCookie(cart.id)); return new Response(null, { status: 303, headers }); }
Anchor to Server-rendered cartServer-rendered cart
Call cartHandlers.get() in a loader and pass the result's data, or a promise of it, to the initialData prop of the cart provider.
Anchor to Type helpersType helpers
CartDataFromQuery types the cart that a custom cart query returns, such as a loader's return value or a component prop. Pass the query's type, such as CartDataFromQuery<typeof CUSTOM_CART_QUERY>. Your query's cart fields replace the matching fields of the default cart data type. A query without a cart field gets the default cart data type.