Version 2.x
Nacelle Storefront SDK 2.x
Links
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
- A greatly improved TypeScript experience
- Full compatibility with 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
- The REST-style data fetching methods, such as
content
,products
,productCollections
, andproductCollectionEntries
provided in Storefront SDK 1.x have been moved to the Commerce Queries Plugin. ThecontentCollections
andcontentCollectionEntries
methods are fully deprecated and are not available in the Commerce Queries plugin. - 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 foronDataError
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 will continue to throw errors instead of returning them to maximize compatibility with Storefront SDK 1.x. - 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. - If using a Node.js version below 18, you must provide the Storefront SDK with a custom fetch implementation via
params.fetchClient
. - Nuxt 2 projects should transpile the Storefront SDK:
export default {
// ...other config,
build: {
// ...other `build` config,
transpile: [
// ...other `transpile` config,
({ isLegacy }) => isLegacy && '@nacelle/storefront-sdk'
],
},
};
Non-breaking changes
- 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. - The
query
method now supports a richer GraphQL querying experience with GraphQL Codegen. This includes the ability to provide thequery
method with aTypedDocumentNode
query for fully typed GraphQL responses when using TypeScript. The revampedquery
method also allows developers to supply queries using the/* GraphQL */
"magic comment" orgraphql-tag
. For more information about using the Storefront SDK with GraphQL Codegen, see our GraphQL Codegen guide. - Defaults to using persisted queries when fetching data. This allows taking advantage of Nacelle's APQ layer for better response times for repeated queries.
- 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
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 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 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. 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.
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:
Initialize the SDK
Import the SDK and initialize it with your Storefront Endpoint from the Nacelle Dashboard.
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
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 docs.
locale
locale
Type: string
An IETF locale string, e.g. 'en-US'.
fetchClient
fetchClient
Type: 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 and 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
exchanges
Type: Exchange
[]
The Storefront SDK uses the urql GraphQL client under the hood. Urql is a flexible GraphQL client that can be customized via 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:
export const defaultExchanges = [
retryExchange,
persistedExchange,
fetchExchange
];
The order of the exchanges in the
exchanges
array matters. Be sure that theretryExchange
andpersistedExchange
come before thefetchExchange
.
retryExchange
- this is Nacelle's pre-configured version of theretryExchange
persistedExchange
- This exchange is configured with the default parameter:
preferGetForPersistedQueries: true
which enables APQ - To turn off APQ, the
exchanges
array should not includepersistedExchange
. For more information, see the "Disabling APQ in Storefront SDK 2.x" recipe.
- This exchange is configured with the default parameter:
fetchExchange
Here's an example of initializing the Storefront SDK parameters with custom exchanges
:
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. It accepts an object with the following properties:
- query - (
TypedDocumentNode | DocumentNode | string
, Required) A GraphQL query. - 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.
Custom Graphql query example
// 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 providedcallback
should be applied to. - callback - (
function
, Required) The callback function that should run after themethod
. 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
returningundefined
. - It can be either synchronous or asynchronous.
- It takes the return value of
- callbackId - (
string
, Optional) A custom identifier for the providedcallback
.- If a
callbackId
isn't specified, an ID will be assigned automatically. - A
callback
will be overwritten if a newcallback
is registered to the samemethod
with the samecallbackId
. - To clear a previously registered
callback
, call theafter
method with themethod
of interest, anull
value forcallback
, and thecallbackId
of the callback that you'd like to clear.
- If a
After examples
// 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 docs.
Updated over 1 year ago