---
updatedAt: 2026-09-07T11:12:39.000Z
agentTools:
  projectIndex: https://docs.nacelle.com/llms.txt
---

# Version 2.x

# Nacelle Storefront SDK 2.x

## Links

* [npm](https://www.npmjs.com/package/@nacelle/storefront-sdk)
* [GitHub](https://github.com/getnacelle/nacelle-js/tree/main/packages/storefront-sdk)
* [BundlePhobia](https://bundlephobia.com/package/@nacelle/storefront-sdk)

## Why upgrade to Storefront SDK version 2.x?

Storefront SDK version 2.x was designed to provide an easy upgrade path from Storefront SDK version 1.x while offering some compelling upgrades for merchants, developers, and end users. New and improved functionality includes:

* An all-new plugin architecture that puts you in control of the features and footprint of the Storefront SDK
* A revamped `.query` method that elevates the GraphQL querying experience
* CDN-powered Storefront GraphQL response caching with Automatic Persisted Queries (APQ) is enabled by default for drastically faster repetitive requests
  * Boosts performance of frontend components that rely on client-side data fetching
  * Speeds up frontend build times by minimizing request times for data fetched for every route, such as header and footer data
* A 60% decrease in package size [removes barriers to frontend performance](https://developer.chrome.com/en/docs/lighthouse/performance/unused-javascript)
* A greatly improved TypeScript experience
  * Full compatibility with [GraphQL Codegen](https://the-guild.dev/graphql/codegen) for a typesafe querying experience with excellent in-editor feedback and autocomplete
  * Commerce queries methods (`.content`, `.products`, etc.) return a single type - no more type assertions!

## What's new in Storefront SDK 2.x?

Storefront SDK 2.x focuses on providing a solid foundation for crafting GraphQL queries for Nacelle's Storefront GraphQL API. This gives developers a high level of control over the data that flows through their eCommerce projects.

### Breaking Changes

1. The REST-style data fetching methods, such as `content`, `products`, `productCollections`, and `productCollectionEntries` provided in Storefront SDK 1.x have been moved to the [Commerce Queries Plugin](https://docs.nacelle.com/docs/storefront-sdk-commerce-queries-plugin). The `contentCollections` and `contentCollectionEntries` methods are fully deprecated and are not available in the Commerce Queries plugin.
2. For the `.query` method, the SDK no longer throws on errors. Instead, it returns a result object of the more standard GraphQL response in the form of `{ data, error }`. This allows developers better control of how to handle errors. A function for `onDataError` can no longer be provided to the SDK. Users of Storefront SDK 1.x's `.query` method will need to be aware of these changes. The additional methods provided by the [Commerce Queries Plugin](https://docs.nacelle.com/docs/storefront-sdk-commerce-queries-plugin) will continue to throw errors instead of returning them to maximize compatibility with Storefront SDK 1.x.
3. The Storefront function used to create the SDK was removed. Instead, the Storefront SDK is initialized as a new instance of the `StorefrontClient` class, which can be wrapped with Storefront SDK plugins for additional functionality.
4. If using a Node.js version below 18, you must provide the Storefront SDK with a custom [fetch](https://fetch.spec.whatwg.org) implementation via `params.fetchClient`.
5. Nuxt 2 projects should transpile the Storefront SDK:

```javascript nuxt.config.js
export default {
  // ...other config,
  build: {
    // ...other `build` config,
    transpile: [
      // ...other `transpile` config,
      ({ isLegacy }) => isLegacy && '@nacelle/storefront-sdk'
    ],
  },
};
```

### Non-breaking changes

1. A fetch client can be provided to the Storefront SDK on initialization. This option can be useful when using the SDK in environments where the `fetch` API is not globally available.
2. The `query` method now supports a richer GraphQL querying experience with [GraphQL Codegen](https://the-guild.dev/graphql/codegen). This includes the ability to provide the `query` method with a [`TypedDocumentNode`](https://github.com/dotansimha/graphql-typed-document-node#graphql-typed-document-node) query for fully typed GraphQL responses when using TypeScript. The revamped `query` method also allows developers to supply queries using the `/* GraphQL */` "magic comment" or [`graphql-tag`](https://github.com/apollographql/graphql-tag). For more information about using the Storefront SDK with GraphQL Codegen, see our [GraphQL Codegen guide](https://docs.nacelle.com/docs/graphql-codegen).
3. Defaults to using persisted queries when fetching data. This allows taking advantage of [Nacelle's APQ layer](https://docs.nacelle.com/docs/storefront-graphql-api-stable#automatic-persisted-queries-apq) for better response times for repeated queries.
4. Some config options (such as the Nacelle Space Token) have been removed, while a few new options have been added.

> 📘 For a complete list of changes, check out the [Storefront SDK Changelog](https://docs.nacelle.com/docs/storefront-sdk-changelog)

### New Plugin System

The core of the Storefront SDK version 2.x is focused on providing a first-class querying experience for Nacelle's GraphQL API. To support this, a plugin system was created so that users can opt into additional functionality to best support their needs, while still keeping the core first-class Nacelle querying support provided by the core SDK.

### Commerce Queries Plugin

The [Commerce Queries Plugin](https://docs.nacelle.com/docs/storefront-sdk-commerce-queries-plugin) is designed to support Storefront SDK 1.x users transitioning to Storefront SDK 2.x and supports various use cases that might not need the full control and customization associated with custom GraphQL queries. The plugin extends the Storefront SDK 2.x to add the REST-style methods that exist in the Storefront SDK 1.x (minus the `contentCollections` and `contentCollectionEntries` methods).

> 📘 Storefront SDK 1.x users who want as much compatibility as possible when migrating to the Storefront SDK 2.x *should* use the Commerce Queries plugin.

After upgrading a Storefront SDK 1.x-powered project to use Storefront SDK 2.x, we strongly encourage developers to use the [Strangler Pattern](https://nacelle.com/blog/the-path-to-driving-business-outcomes-with-composable-and-headless-commerce) to incrementally replace Commerce Queries method calls with `query` method calls. This will allow you to remove bloat associated with data payloads that contain fields that are not needed by your project's UI or business logic.

### Automatic Persisted Queries (APQ)

Automatic Persisted Queries (APQ) is a GraphQL caching technique. To learn more about APQ, please see [our Storefront GraphQL API docs](https://docs.nacelle.com/docs/storefront-graphql-api-stable#automatic-persisted-queries-apq). APQ is enabled in Storefront SDK 2.x by default, which makes it easy to take advantage of APQ's performance benefits.

We recommend leaving APQ enabled. If you need to disable APQ to accommodate an advanced use case, refer to [the "Disabling APQ in Storefront SDK 2.x" recipe](https://docs.nacelle.com/recipes/disabling-apq-in-storefront-sdk-2x).

## Adding to a project

### Install

Begin by installing the `@latest` version of the Storefront SDK in your Node.js project:

```
npm i @nacelle/storefront-sdk@latest
```

### Get credentials from the Nacelle Dashboard

Retrieve the **Storefront Endpoint**  from the Nacelle Dashboard:

[block:image]
{
  "images": [
    {
      "image": [
        "https://files.readme.io/67268c1-Nacelle_Dashboard_Storefront_API_section_with_Storefront_Endpoint_focus.png",
        null,
        "A screenshot from the Nacelle Dashboard's Space Settings > API Details page. The Storefront API section contains a field for \"Storefront Endpoint.\" This field has a copy button on the right side of the field. Clicking this button copies the value of the field."
      ],
      "align": "center",
      "caption": "The **Storefront Endpoint**  can be copied with a press of a button."
    }
  ]
}
[/block]

### Initialize the SDK

Import the SDK and initialize it with your Storefront Endpoint from the Nacelle Dashboard.

```typescript
import { StorefrontClient } from '@nacelle/storefront-sdk';

const client = new StorefrontClient({
  storefrontEndpoint: '<your-nacelle-storefront-api-endpoint>',
});
```

In addition to the (required) `storefrontEndpoint`, the Storefront SDK accepts the following initialization parameters:

### Optional initialization parameters

#### `previewToken`

**Type**: `string`

A Nacelle Storefront GraphQL preview token. When supplied, the Storefront SDK will enter preview mode globally. To learn more, check out the [Preview Mode](https://docs.nacelle.com/docs/preview-data#storefront-sdk) docs.

#### `locale`

**Type**: `string`

An IETF locale string, e.g. 'en-US'.

#### `fetchClient`

**Type**: [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/fetch)

A custom fetch implementation. By default, the Storefront SDK uses `globalThis.fetch` for network requests. You can supply a custom `fetchClient` to use instead of `globalThis.fetch`. This is required if using the Storefront SDK with Node.js versions less than 18, because Node.js versions below 18 did not implement `globalThis.fetch`. Examples of custom fetch implementations include [cross-fetch](https://www.npmjs.com/package/cross-fetch) and [isomorphic-unfetch](https://www.npmjs.com/package/isomorphic-unfetch). If using Node.js 18 and above, we recommend not specifying a `fetchClient`, unless a custom fetch implementation is needed to satisfy advanced use cases.

#### `exchanges`

**Type**: [`Exchange`](https://formidable.com/open-source/urql/docs/api/core/#exchange)`[]`

The Storefront SDK uses the [urql](https://formidable.com/open-source/urql/) GraphQL client under the hood. Urql is a flexible GraphQL client that can be customized via [exchanges](https://formidable.com/open-source/urql/docs/architecture/#the-client-and-exchanges). The Storefront SDK exports an array of `defaultExchanges`; these are used by default unless custom `exchanges` are specified in the Storefront SDK's initialization params. The default exchanges are:

```typescript
export const defaultExchanges = [
  retryExchange,
  persistedExchange,
  fetchExchange
];
```

> 🚧 The order of the [exchanges](https://formidable.com/open-source/urql/docs/architecture/#the-client-and-exchanges) in the `exchanges` array matters. Be sure that the `retryExchange` and `persistedExchange` come before the `fetchExchange`.

* `retryExchange` - this is Nacelle's pre-configured version of the [`retryExchange`](https://formidable.com/open-source/urql/docs/api/retry-exchange/)
* [`persistedExchange`](https://github.com/urql-graphql/urql/tree/main/exchanges/persisted)
  * This exchange is configured with the default parameter: `preferGetForPersistedQueries: true` which enables [APQ](/docs/storefront-graphql-api-stable#automatic-persisted-queries-apq)
  * To turn off APQ, the `exchanges` array should not include `persistedExchange`. For more information, see [the "Disabling APQ in Storefront SDK 2.x" recipe](https://docs.nacelle.com/recipes/disabling-apq-in-storefront-sdk-2x).
* [`fetchExchange`](https://formidable.com/open-source/urql/docs/api/core/#fetchexchange)

Here's an example of initializing the Storefront SDK parameters with custom `exchanges`:

```typescript TypeScript
import {
  StorefrontClient,
  retryExchange,
  persistedExchange,
  fetchExchange
} from '@nacelle/storefront-sdk';

const client = new StorefrontClient({
  storefrontEndpoint: '<my-storefront-endpoint>',
  exchanges: [
    retryExchange,
    persistedExchange,
    myCustomUrqlExchange,
    fetchExchange
  ]
});
```

## Data Fetching

### Crafting GraphQL queries

The `query` method submits GraphQL requests to the [Nacelle Storefront GraphQL API](https://docs.nacelle.com/docs/storefront-graphql-api-stable). It accepts an object with the following properties:

* **query** - (`TypedDocumentNode | DocumentNode | string`, Required) A GraphQL [query](https://graphql.org/learn/queries).
* **variables** - (`Record<string, unknown> | string`, Optional) Object or stringified object containing any GraphQL variables used in the query.

The `query` method returns an object with the following properties:

* **data** - The GraphQL data response.
* **error** - [Combined Network + GraphQL errors](https://formidable.com/open-source/urql/docs/basics/errors).

### Custom Graphql query example

```typescript
// Get product handles from the 'collection-1' collection
const query = /* GraphQL */ `
  query ProductHandles($filter: ProductCollectionFilterInput) {
    allProductCollections(filter: $filter) {
      edges {
        node {
          productConnection {
            edges {
              node {
                content {
                  handle
                }
              }
            }
          }
        }
      }
    }
  }
`;

const variables = {
  filter: {
    handles: 'collection-1'
  }
};

const { data, error } = await client.query({ query, variables });
```

### Transforming the responses of SDK methods

The Storefront SDK offers an `after`  method that lets you run arbitrary transformations or side-effects when other Storefront SDK methods are called. The `after` method is very flexible and can be a practical tool for accommodating edge cases.

The `after` method accepts three positional arguments, `method`, `callback`, and `callbackId`:

* **method** - (`string`, Required) The target method that the provided `callback` should be applied to.
* **callback** - (`function`, Required) The callback function that should run after the `method`. The callback function has the following characteristics:
  * It takes the return value of `method` as input.
  * It should return either the unaltered input or a transformed version of the input. Failure to return a value from the callback will result in the `method` returning `undefined`.
  * It can be either synchronous or asynchronous.
* **callbackId** - (`string`, Optional) A custom identifier for the provided `callback`.
  * If a `callbackId` isn't specified, an ID will be assigned automatically.
  * A `callback` will be overwritten if a new `callback` is registered to the same `method` with the same `callbackId`.
  * To clear a previously registered `callback`, call the `after` method with the `method` of interest, a `null` value for `callback`, and the `callbackId` of the callback that you'd like to clear.

#### After examples

```typescript
// NOTE: The examples below demonstrate using the `after` method
// with data-fetching methods added by the Commerce Queries plugin.

// Example 1: Capitalizing the `product.title` of all product data returned by the `products` method

const capitalizeTitle = (words) =>
  words
    .split(' ')
    .map((word) => `${word.charAt(0).toUpperCase()}${word.slice(1)}`)
    .join(' ');

client.after('products', (products) =>
  // return a transformed version of the `products` data
  products.map((product) => ({
    ...product,
    title: capitalizeTitle(product.title)
  }))
);

await client.products(); // returns `products` with capitalized `product.title`s

// Example 2: Performing asynchronous side effects when the `content` method is called

client.after('content', async (contentEntries) => {
  const contentIds = contentEntries.map((entry) => entry.nacelleEntryId);

  // Register an event with a third-party service
  await observabilityClient.addEvent({
    type: 'content data requested',
    data: contentIds
  });

  return contentEntries; // Because we aren't transforming the data, we can return the
  // original `contentEntries` fetched by the `content` method
});

await client.content({ type: 'teamBio' }); // reports an event with the `observabilityClient`
```

### Preview mode

Preview mode can be activated in the SDK either globally or on-the-fly. To learn more, check out the [Preview Mode](https://docs.nacelle.com/docs/preview-data#storefront-sdk) docs.