---
title: createHydrogenContext
description: >-

  The `createHydrogenContext` function creates the context object required to
  use Hydrogen utilities throughout a Hydrogen project.
api_version: 2024-10
api_name: hydrogen
source_url:
  html: >-
    https://shopify.dev/docs/api/hydrogen/2024-10/utilities/createhydrogencontext
  md: >-
    https://shopify.dev/docs/api/hydrogen/2024-10/utilities/createhydrogencontext.md
---

# create​Hydrogen​Context

The `createHydrogenContext` function creates the context object required to use Hydrogen utilities throughout a Hydrogen project.

## createHydrogenContext(options)

* **env**

  **TEnv**

  **required**

* **request**

  **CrossRuntimeRequest**

  **required**

* **session**

  **TSession**

  **required**

  Any cookie implementation. By default Hydrogen ships with cookie session storage, but you can use [another session storage](https://remix.run/docs/en/main/utils/sessions) implementation.

* **cache**

  **Cache**

  An instance that implements the [Cache API](https://developer.mozilla.org/en-US/docs/Web/API/Cache)

* **cart**

  **{ getId?: () => string; setId?: (cartId: string) => Headers; queryFragment?: string; mutateFragment?: string; customMethods?: Record\<string, Function>; }**

  Cart handler overwrite options. See documentation for createCartHandler for more information.

* **customerAccount**

  **{ apiVersion?: string; authUrl?: string; customAuthStatusHandler?: () => {} | Response; unstableB2b?: boolean; }**

  Customer Account client overwrite options. See documentation for createCustomerAccountClient for more information.

* **i18n**

  **TI18n**

  An object containing a country code and language code

* **logErrors**

  **boolean | ((error?: Error) => boolean)**

  Whether it should print GraphQL errors automatically. Defaults to true

* **storefront**

  **{ headers?: StorefrontHeaders; apiVersion?: string; }**

  Storefront client overwrite options. See documentation for createStorefrontClient for more information.

* **waitUntil**

  **WaitUntil**

  The `waitUntil` function is used to keep the current request/response lifecycle alive even after a response has been sent. It should be provided by your platform.

### Headers



### CrossRuntimeRequest

* headers

  ```ts
  { [key: string]: any; get?: (key: string) => string; }
  ```

* method

  ```ts
  string
  ```

* url

  ```ts
  string
  ```

## Returns

* **cart**

  **TCustomMethods extends CustomMethodsBase ? HydrogenCartCustom\<TCustomMethods> : HydrogenCart**

  **required**

  A collection of utilities used to interact with the cart.

* **customerAccount**

  **CustomerAccount**

  **required**

  A GraphQL client for querying the [Customer Account API](https://shopify.dev/docs/api/customer). It also provides methods to authenticate and check if the user is logged in.

* **env**

  **TEnv**

  **required**

* **session**

  **TSession**

  **required**

  Any cookie implementation. By default Hydrogen ships with cookie session storage, but you can use [another session storage](https://remix.run/docs/en/main/utils/sessions) implementation.

* **storefront**

  **Storefront\<TI18n>**

  **required**

  A GraphQL client for querying the [Storefront API](https://shopify.dev/docs/api/storefront).

* **waitUntil**

  **WaitUntil**

  The `waitUntil` function is used to keep the current request/response lifecycle alive even after a response has been sent. It should be provided by your platform.

### CustomMethodsBase



### HydrogenCartCustom

```ts
Omit<HydrogenCart, keyof TCustomMethods> & TCustomMethods
```

### HydrogenCart

* addLines

  ```ts
  ReturnType<typeof cartLinesAddDefault>
  ```

* create

  ```ts
  ReturnType<typeof cartCreateDefault>
  ```

* deleteMetafield

  ```ts
  ReturnType<typeof cartMetafieldDeleteDefault>
  ```

* get

  ```ts
  ReturnType<typeof cartGetDefault>
  ```

* getCartId

  ```ts
  () => string
  ```

* removeLines

  ```ts
  ReturnType<typeof cartLinesRemoveDefault>
  ```

* setCartId

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

* setMetafields

  ```ts
  ReturnType<typeof cartMetafieldsSetDefault>
  ```

* updateAttributes

  ```ts
  ReturnType<typeof cartAttributesUpdateDefault>
  ```

* updateBuyerIdentity

  ```ts
  ReturnType<typeof cartBuyerIdentityUpdateDefault>
  ```

* updateDiscountCodes

  ```ts
  ReturnType<typeof cartDiscountCodesUpdateDefault>
  ```

* updateGiftCardCodes

  ```ts
  ReturnType<typeof cartGiftCardCodesUpdateDefault>
  ```

* updateLines

  ```ts
  ReturnType<typeof cartLinesUpdateDefault>
  ```

* updateNote

  ```ts
  ReturnType<typeof cartNoteUpdateDefault>
  ```

* updateSelectedDeliveryOption

  ```ts
  ReturnType<
      typeof cartSelectedDeliveryOptionsUpdateDefault
    >
  ```

### Headers



### CustomerAccount

* authorize

  On successful login, the customer redirects back to your app. This function validates the OAuth response and exchanges the authorization code for an access token and refresh token. It also persists the tokens on your session. This function should be called and returned from the Remix loader configured as the redirect URI within the Customer Account API settings in admin.

  ```ts
  () => Promise<Response>
  ```

* getAccessToken

  Returns CustomerAccessToken if the customer is logged in. It also run a expiry check and does a token refresh if needed.

  ```ts
  () => Promise<string>
  ```

* getApiUrl

  Creates the fully-qualified URL to your store's GraphQL endpoint.

  ```ts
  () => string
  ```

* handleAuthStatus

  Check for a not logged in customer and redirect customer to login page. The redirect can be overwritten with \`customAuthStatusHandler\` option.

  ```ts
  () => void | DataFunctionValue
  ```

* isLoggedIn

  Returns if the customer is logged in. It also checks if the access token is expired and refreshes it if needed.

  ```ts
  () => Promise<boolean>
  ```

* login

  Start the OAuth login flow. This function should be called and returned from a Remix action. It redirects the customer to a Shopify login domain. It also defined the final path the customer lands on at the end of the oAuth flow with the value of the \`return\_to\` query param. (This is automatically setup unless \`customAuthStatusHandler\` option is in use)

  ```ts
  (options?: LoginOptions) => Promise<Response>
  ```

* logout

  Logout the customer by clearing the session and redirecting to the login domain. It should be called and returned from a Remix action. The path app should redirect to after logout can be setup in Customer Account API settings in admin.

  ```ts
  (options?: LogoutOptions) => Promise<Response>
  ```

* mutate

  Execute a GraphQL mutation against the Customer Account API. This method execute \`handleAuthStatus()\` ahead of mutation.

  ```ts
  <OverrideReturnType extends unknown = never, RawGqlString extends string = string>(mutation: RawGqlString, ...options: IsOptionalVariables<CustomerAccountMutations[RawGqlString]["variables"], never, Omit<CustomerAccountMutations[RawGqlString]["variables"], never>> extends true ? [({} & ClientVariables<CustomerAccountMutations, RawGqlString, never, "variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof CustomerAccountMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof CustomerAccountMutations[RawGqlString]["variables"], never>>]: CustomerAccountMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<CustomerAccountMutations[RawGqlString]["variables"], Extract<keyof CustomerAccountMutations[RawGqlString]["variables"], never>>>)]: ({ [KeyType in keyof CustomerAccountMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof CustomerAccountMutations[RawGqlString]["variables"], never>>]: CustomerAccountMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<CustomerAccountMutations[RawGqlString]["variables"], Extract<keyof CustomerAccountMutations[RawGqlString]["variables"], never>>>)[KeyType]; } : { readonly [variable: string]: unknown; }, Record<"variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof CustomerAccountMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof CustomerAccountMutations[RawGqlString]["variables"], never>>]: CustomerAccountMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<CustomerAccountMutations[RawGqlString]["variables"], Extract<keyof CustomerAccountMutations[RawGqlString]["variables"], never>>>)]: ({ [KeyType in keyof CustomerAccountMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof CustomerAccountMutations[RawGqlString]["variables"], never>>]: CustomerAccountMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<CustomerAccountMutations[RawGqlString]["variables"], Extract<keyof CustomerAccountMutations[RawGqlString]["variables"], never>>>)[KeyType]; } : { readonly [variable: string]: unknown; }>>)?] : [{} & ClientVariables<CustomerAccountMutations, RawGqlString, never, "variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof CustomerAccountMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof CustomerAccountMutations[RawGqlString]["variables"], never>>]: CustomerAccountMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<CustomerAccountMutations[RawGqlString]["variables"], Extract<keyof CustomerAccountMutations[RawGqlString]["variables"], never>>>)]: ({ [KeyType in keyof CustomerAccountMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof CustomerAccountMutations[RawGqlString]["variables"], never>>]: CustomerAccountMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<CustomerAccountMutations[RawGqlString]["variables"], Extract<keyof CustomerAccountMutations[RawGqlString]["variables"], never>>>)[KeyType]; } : { readonly [variable: string]: unknown; }, Record<"variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof CustomerAccountMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof CustomerAccountMutations[RawGqlString]["variables"], never>>]: CustomerAccountMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<CustomerAccountMutations[RawGqlString]["variables"], Extract<keyof CustomerAccountMutations[RawGqlString]["variables"], never>>>)]: ({ [KeyType in keyof CustomerAccountMutations[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof CustomerAccountMutations[RawGqlString]["variables"], never>>]: CustomerAccountMutations[RawGqlString]["variables"][KeyType]; } & Partial<Pick<CustomerAccountMutations[RawGqlString]["variables"], Extract<keyof CustomerAccountMutations[RawGqlString]["variables"], never>>>)[KeyType]; } : { readonly [variable: string]: unknown; }>>]) => Promise<Omit<CustomerAPIResponse<ClientReturn<CustomerAccountMutations, RawGqlString, OverrideReturnType>>, "errors"> & { errors?: Pick<GraphQLError, "name" | "message" | "path" | "extensions" | "locations" | "stack">[]; }>
  ```

* query

  Execute a GraphQL query against the Customer Account API. This method execute \`handleAuthStatus()\` ahead of query.

  ```ts
  <OverrideReturnType extends unknown = never, RawGqlString extends string = string>(query: RawGqlString, ...options: IsOptionalVariables<CustomerAccountQueries[RawGqlString]["variables"], never, Omit<CustomerAccountQueries[RawGqlString]["variables"], never>> extends true ? [({} & ClientVariables<CustomerAccountQueries, RawGqlString, never, "variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof CustomerAccountQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof CustomerAccountQueries[RawGqlString]["variables"], never>>]: CustomerAccountQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<CustomerAccountQueries[RawGqlString]["variables"], Extract<keyof CustomerAccountQueries[RawGqlString]["variables"], never>>>)]: ({ [KeyType in keyof CustomerAccountQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof CustomerAccountQueries[RawGqlString]["variables"], never>>]: CustomerAccountQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<CustomerAccountQueries[RawGqlString]["variables"], Extract<keyof CustomerAccountQueries[RawGqlString]["variables"], never>>>)[KeyType]; } : { readonly [variable: string]: unknown; }, Record<"variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof CustomerAccountQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof CustomerAccountQueries[RawGqlString]["variables"], never>>]: CustomerAccountQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<CustomerAccountQueries[RawGqlString]["variables"], Extract<keyof CustomerAccountQueries[RawGqlString]["variables"], never>>>)]: ({ [KeyType in keyof CustomerAccountQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof CustomerAccountQueries[RawGqlString]["variables"], never>>]: CustomerAccountQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<CustomerAccountQueries[RawGqlString]["variables"], Extract<keyof CustomerAccountQueries[RawGqlString]["variables"], never>>>)[KeyType]; } : { readonly [variable: string]: unknown; }>>)?] : [{} & ClientVariables<CustomerAccountQueries, RawGqlString, never, "variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof CustomerAccountQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof CustomerAccountQueries[RawGqlString]["variables"], never>>]: CustomerAccountQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<CustomerAccountQueries[RawGqlString]["variables"], Extract<keyof CustomerAccountQueries[RawGqlString]["variables"], never>>>)]: ({ [KeyType in keyof CustomerAccountQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof CustomerAccountQueries[RawGqlString]["variables"], never>>]: CustomerAccountQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<CustomerAccountQueries[RawGqlString]["variables"], Extract<keyof CustomerAccountQueries[RawGqlString]["variables"], never>>>)[KeyType]; } : { readonly [variable: string]: unknown; }, Record<"variables", RawGqlString extends never ? { [KeyType in keyof ({ [KeyType in keyof CustomerAccountQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof CustomerAccountQueries[RawGqlString]["variables"], never>>]: CustomerAccountQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<CustomerAccountQueries[RawGqlString]["variables"], Extract<keyof CustomerAccountQueries[RawGqlString]["variables"], never>>>)]: ({ [KeyType in keyof CustomerAccountQueries[RawGqlString]["variables"] as Filter<KeyType, Extract<keyof CustomerAccountQueries[RawGqlString]["variables"], never>>]: CustomerAccountQueries[RawGqlString]["variables"][KeyType]; } & Partial<Pick<CustomerAccountQueries[RawGqlString]["variables"], Extract<keyof CustomerAccountQueries[RawGqlString]["variables"], never>>>)[KeyType]; } : { readonly [variable: string]: unknown; }>>]) => Promise<Omit<CustomerAPIResponse<ClientReturn<CustomerAccountQueries, RawGqlString, OverrideReturnType>>, "errors"> & { errors?: Pick<GraphQLError, "name" | "message" | "path" | "extensions" | "locations" | "stack">[]; }>
  ```

* UNSTABLE\_getBuyer

  UNSTABLE feature. Get buyer token and company location id from session.

  ```ts
  () => Promise<BuyerInput>
  ```

* UNSTABLE\_setBuyer

  UNSTABLE feature. Set buyer information into session.

  ```ts
  (buyer: BuyerInput) => void
  ```

### DataFunctionValue

```ts
Response | NonNullable<unknown> | null
```

### LoginOptions

* uiLocales

  ```ts
  LanguageCode
  ```

### LogoutOptions

* headers

  ```ts
  HeadersInit
  ```

* postLogoutRedirectUri

  ```ts
  string
  ```

### CustomerAccountMutations



### CustomerAPIResponse

* data

  ```ts
  ReturnType
  ```

* errors

  ```ts
  Array<{
      message: string;
      locations?: Array<{line: number; column: number}>;
      path?: Array<string>;
      extensions: {code: string};
    }>
  ```

* extensions

  ```ts
  { cost: { requestQueryCost: number; actualQueryCakes: number; throttleStatus: { maximumAvailable: number; currentAvailable: number; restoreRate: number; }; }; }
  ```

### GraphQLError

* locations

  If an error can be associated to a particular point in the requested GraphQL document, it should contain a list of locations.

  ```ts
  { line: number; column: number; }[]
  ```

* path

  If an error can be associated to a particular field in the GraphQL result, it \_must\_ contain an entry with the key \`path\` that details the path of the response field which experienced the error. This allows clients to identify whether a null result is intentional or caused by a runtime error.

  ```ts
  (string | number)[]
  ```

* extensions

  Reserved for implementors to extend the protocol however they see fit, and hence there are no additional restrictions on its contents.

  ```ts
  { [key: string]: unknown; }
  ```

* toString

  Note: \`toString()\` is internally used by \`console.log(...)\` / \`console.error(...)\` when ingesting logs in Oxygen production. Therefore, we want to make sure that the error message is as informative as possible instead of \`\[object Object]\`.

  ```ts
  () => string
  ```

* toJSON

  Note: toJSON\` is internally used by \`JSON.stringify(...)\`. The most common scenario when this error instance is going to be stringified is when it's passed to Remix' \`json\` and \`defer\` functions: e.g. \`defer({promise: storefront.query(...)})\`. In this situation, we don't want to expose private error information to the browser so we only do it in development.

  ```ts
  () => Pick<GraphQLError, "name" | "message" | "path" | "extensions" | "locations" | "stack">
  ```

* \_\_@toStringTag\@663

  ```ts
  string
  ```

* name

  ```ts
  string
  ```

* message

  ```ts
  string
  ```

* stack

  ```ts
  string
  ```

### CustomerAccountQueries



### Storefront

Interface to interact with the Storefront API.

* cache

  ```ts
  Cache
  ```

* CacheCustom

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

* CacheLong

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

* CacheNone

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

* CacheShort

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

* forward

  Forwards the request to the Storefront API. It reads the API version from the request URL.

  ```ts
  (request: Request, options?: Pick<StorefrontCommonExtraParams, "storefrontApiVersion">) => Promise<Response>
  ```

* generateCacheControlHeader

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

* getApiUrl

  ```ts
  any
  ```

* getHeaders

  ```ts
  () => Record<string, string>
  ```

* getPrivateTokenHeaders

  ```ts
  any
  ```

* getPublicTokenHeaders

  ```ts
  any
  ```

* getShopifyDomain

  ```ts
  any
  ```

* i18n

  ```ts
  TI18n
  ```

* isStorefrontApiUrl

  Checks if the request URL matches the Storefront API GraphQL endpoint.

  ```ts
  (request: { url?: string; }) => boolean
  ```

* mutate

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

* query

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

* setCollectedSubrequestHeaders

  Sets the collected subrequest headers in the response. Useful to forward the cookies and server-timing headers from server subrequests to the browser.

  ```ts
  (response: { headers: Headers; }) => void
  ```

### AllCacheOptions

Override options for a cache strategy.

* maxAge

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

  ```ts
  number
  ```

* mode

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

  ```ts
  string
  ```

* sMaxAge

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

  ```ts
  number
  ```

* staleIfError

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

  ```ts
  number
  ```

* staleWhileRevalidate

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

  ```ts
  number
  ```

### NoStoreStrategy

* mode

  ```ts
  string
  ```

### StorefrontCommonExtraParams

* displayName

  ```ts
  string
  ```

* headers

  ```ts
  HeadersInit
  ```

* storefrontApiVersion

  ```ts
  string
  ```

### StorefrontMutations

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



### AutoAddedVariableNames

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

### StorefrontError

* errors

  ```ts
  StorefrontApiErrors
  ```

### StorefrontApiErrors

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

### JsonGraphQLError



### StorefrontQueries

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



### StorefrontQueryOptions

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

### CachingStrategy

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

* maxAge

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

  ```ts
  number
  ```

* mode

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

  ```ts
  string
  ```

* sMaxAge

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

  ```ts
  number
  ```

* staleIfError

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

  ```ts
  number
  ```

* staleWhileRevalidate

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

  ```ts
  number
  ```

Examples

### Examples

* #### Example code

  ##### Description

  I am the default example

  ##### JavaScript

  ```jsx
  import {createHydrogenContext} from '@shopify/hydrogen';
  import * as remixBuild from '@remix-run/dev/server-build';
  import {
    createRequestHandler,
    createCookieSessionStorage,
  } from '@shopify/remix-oxygen';

  export default {
    async fetch(request, env, executionContext) {
      const waitUntil = executionContext.waitUntil.bind(executionContext);
      const [cache, session] = await Promise.all([
        caches.open('hydrogen'),
        AppSession.init(request, [env.SESSION_SECRET]),
      ]);

      /* Create context objects required to use Hydrogen with your credentials and options */
      const hydrogenContext = createHydrogenContext({
        /* Environment variables from the fetch function */
        env,
        /* Request object from the fetch function */
        request,
        /* Cache API instance */
        cache,
        /* Runtime utility in serverless environments */
        waitUntil,
        session,
      });

      const handleRequest = createRequestHandler({
        build: remixBuild,
        mode: process.env.NODE_ENV,
        /* Inject the customer account client in the Remix context */
        getLoadContext: () => ({...hydrogenContext}),
      });

      const response = await handleRequest(request);

      if (session.isPending) {
        response.headers.set('Set-Cookie', await session.commit());
      }

      return response;
    },
  };

  class AppSession {
    isPending = false;

    static async init(request, secrets) {
      const storage = createCookieSessionStorage({
        cookie: {
          name: 'session',
          httpOnly: true,
          path: '/',
          sameSite: 'lax',
          secrets,
        },
      });

      const session = await storage.getSession(request.headers.get('Cookie'));

      return new this(storage, session);
    }

    get(key) {
      return this.session.get(key);
    }

    destroy() {
      return this.sessionStorage.destroySession(this.session);
    }

    flash(key, value) {
      this.session.flash(key, value);
    }

    unset(key) {
      this.isPending = true;
      this.session.unset(key);
    }

    set(key, value) {
      this.isPending = true;
      this.session.set(key, value);
    }

    commit() {
      this.isPending = false;
      return this.sessionStorage.commitSession(this.session);
    }
  }
  ```

  ##### TypeScript

  ```tsx
  import {createHydrogenContext, type HydrogenSession} from '@shopify/hydrogen';
  import * as remixBuild from '@remix-run/dev/server-build';
  import {
    createRequestHandler,
    createCookieSessionStorage,
    type SessionStorage,
    type Session,
  } from '@shopify/remix-oxygen';

  export default {
    async fetch(request: Request, env: Env, executionContext: ExecutionContext) {
      const waitUntil = executionContext.waitUntil.bind(executionContext);
      const [cache, session] = await Promise.all([
        caches.open('hydrogen'),
        AppSession.init(request, [env.SESSION_SECRET]),
      ]);

      /* Create context objects required to use Hydrogen with your credentials and options */
      const hydrogenContext = createHydrogenContext({
        /* Environment variables from the fetch function */
        env,
        /* Request object from the fetch function */
        request,
        /* Cache API instance */
        cache,
        /* Runtime utility in serverless environments */
        waitUntil,
        session,
      });

      const handleRequest = createRequestHandler({
        build: remixBuild,
        mode: process.env.NODE_ENV,
        /* Inject the customer account client in the Remix context */
        getLoadContext: () => ({...hydrogenContext}),
      });

      const response = await handleRequest(request);

      if (session.isPending) {
        response.headers.set('Set-Cookie', await session.commit());
      }

      return response;
    },
  };

  class AppSession implements HydrogenSession {
    public isPending = false;

    constructor(
      private sessionStorage: SessionStorage,
      private session: Session,
    ) {}

    static async init(request: Request, secrets: string[]) {
      const storage = createCookieSessionStorage({
        cookie: {
          name: 'session',
          httpOnly: true,
          path: '/',
          sameSite: 'lax',
          secrets,
        },
      });

      const session = await storage.getSession(request.headers.get('Cookie'));

      return new this(storage, session);
    }

    get(key: string) {
      return this.session.get(key);
    }

    destroy() {
      return this.sessionStorage.destroySession(this.session);
    }

    flash(key: string, value: any) {
      this.session.flash(key, value);
    }

    unset(key: string) {
      this.isPending = true;
      this.session.unset(key);
    }

    set(key: string, value: any) {
      this.isPending = true;
      this.session.set(key, value);
    }

    commit() {
      this.isPending = false;
      return this.sessionStorage.commitSession(this.session);
    }
  }
  ```

## Related

[- createHydrogenContext](https://shopify.dev/docs/api/hydrogen/2024-10/utilities/createhydrogencontext)
