---
title: Storefront API
description: How the template calls Shopify's Storefront GraphQL API - the fetch client, query patterns, caching, and error handling.
type: reference
prerequisites:
  - /docs/getting-started
---

# Storefront API



The template uses [Shopify Hydrogen](https://www.npmjs.com/package/@shopify/hydrogen) for Storefront GraphQL API queries and mutations. Configure its domain, public token, and API version with the variables in [Environment Variables](/docs/reference/env-vars). Grant the scopes in [Storefront API Permissions](/docs/reference/storefront-api-permissions).

The Customer Account API uses a separate endpoint, schema, client ID, and session secret. Its documents use `gql` from `@shopify/hydrogen/customer-account` and are typed by Hydrogen; Storefront API codegen does not validate them.

## Write and validate operations

Define each operation with Hydrogen's `gql()` tag and pass dynamic values as GraphQL variables. Do not interpolate runtime values or conditional fields into the document. Compose shared selections by passing fragment documents as the second argument.

Result and variable types are inferred from the document, so the request wrapper returns typed data without a hand-written response type. Include Shopify's `@inContext` directive when localized pricing or content depends on country and language; the wrapper fills `$country` and `$language` from the `locale` option:

```ts
import { gql } from "@shopify/hydrogen";

const GET_PRODUCT_QUERY = gql(`#graphql
  query getProduct(
    $handle: String!
    $country: CountryCode
    $language: LanguageCode
  ) @inContext(country: $country, language: $language) {
    productByHandle(handle: $handle) {
      id
      title
    }
  }
`);

const response = await storefront.request(GET_PRODUCT_QUERY, {
  locale,
  variables: { handle },
});
```

Validate current field names, arguments, and types with Shopify AI Toolkit. Then use the [`shopify-graphql-reference` skill](/docs/skills/shopify-graphql-reference) for template integration conventions. The skill is not a schema source.

## Codegen

Type inference does not reject unknown fields, so the template keeps a schema check. It runs [`@shopify/api-codegen-preset`](https://www.npmjs.com/package/@shopify/api-codegen-preset) over every Storefront `#graphql` document:

```bash
pnpm --filter template codegen
```

Codegen reads `SHOPIFY_API_VERSION` and fails when an operation does not match Shopify's live schema. Development runs codegen without blocking startup, while the production build treats failure as a hard error. Generated validation files are gitignored.

## Caching

Choose caching by data sensitivity and behavior:

| Data or operation                                          | Cache contract                                                |
| ---------------------------------------------------------- | ------------------------------------------------------------- |
| Public product, collection, menu, or content data          | Cache and invalidate when Shopify changes                     |
| Public results that vary by filters, search, or pagination | Share only when the cache key includes every varying input    |
| Cart, session, authorization, or customer data             | Keep request-scoped or private; never place in a public cache |
| Mutations                                                  | Do not cache                                                  |

Webhook-driven invalidation keeps cached Shopify content current. Configure `POST /api/webhooks/shopify` as described in [Webhooks](/docs/anatomy/webhooks).

## Mutations

Cart mutations are uncached and return the updated cart. Use the returned cart instead of issuing a follow-up read.

Never cache cart IDs, customer data, session data, or authenticated responses in a shared public cache.

## Errors and missing resources

Storefront requests throw on transport failures, timeouts, and GraphQL failures without usable data. A response with both data and GraphQL errors logs a warning and allows the operation to use the partial data.

A missing resource is not an API failure. Read operations return `undefined`, `null`, or an empty list when the requested resource does not exist.

Set `DEBUG_SHOPIFY=true` to include structured Storefront and Customer Account API operation timings in server logs. Warnings and errors remain enabled when debug logging is off.


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)