Version 1.x

Adding to a project

Install

Begin by installing the Storefront SDK in your Node.js project:

npm i @nacelle/storefront-sdk

Get credentials from the Nacelle Dashboard

Retrieve the Storefront Endpoint and Public Storefront Token from the Nacelle Dashboard:

A screenshot from the Nacelle Dashboard's Space Settings > API Details page. The Storefront API section contains fields for "Storefront Endpoint" and "Public Storefront Token." Each of these fields has a copy button on the right side of the field. Clicking this button copies the value of the field.

The Storefront Endpoint and Public Storefront Token can be copied with a press of a button.

Initialize the SDK

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

import Storefront from '@nacelle/storefront-sdk';

const client = Storefront({
  storefrontEndpoint: '<your-storefront-endpoint>',
  token: '<your-public-storefront-token>',
  locale: 'en-US', // Optional, defaults to 'en-US'
  currencyCode: 'USD' // Optional, defaults to 'USD'
});

Querying Data

Products

The products method accepts an object with the following properties to define the options of the query:

  • nacelleEntryIds - (string[], Optional) An array of product.nacelleEntryIds, which are unique IDs assigned to products by Nacelle.

  • handles - (string[], Optional) An array of product handles.

  • locale - (string, Optional, default: 'en-US') An IETF locale.

  • maxReturnedEntries - (Number, Optional) Sets an upper limit on the number of returned products.

  • edgesToNodes - (boolean, Optional, default: true) Sets whether the method returns Product objects or ProductEdge objects. When false, ProductEdge objects are returned. ProductEdges have a cursor and node. The cursor value can be used for paginating; the node contains the product data.

  • cursor - (string, Optional) Returned entries will come after this cursor value.

  • startAfterEntryId - (string, Optional) Returned entries will come after this specified ID. Uses deprecated products Storefront API query. If you need to paginate requests, it is recommended to use the cursor values returned when edgesToNodes is false.

  • advancedOptions - (object, Optional)

    • entriesPerPage - (number, Optional) The SDK is configured to automatically request entries in batches. The number of entries it will attempt to request at a time can be optionally tuned using this parameter.

Products examples

// Get all products in a space
await client.products();

// Get the first 5 products.
await client.products({
  maxReturnedEntries: 5
});

// Get products by handles.
await client.products({
  handles: ['product-1', 'product-2']
});

// Get products after a specified ID.
await client.products({
  startAfterEntryId: 'someNacelleEntryId'
});

// Using cursors to manually retrieve paginated results
const batchOne = await client.products({
  maxReturnedEntries: 5,
  edgesToNodes: false
});

const batchTwo = await client.products({
  maxReturnedEntries: 5,
  edgesToNodes: false,
  cursor: batchOne.at(-1).cursor
});

// When using Typescript
const [firstProductEdge] = await client.products({
  maxReturnedEntries: 5,
  edgesToNodes: false
});
const { cursor, edge } = firstProductEdge as ProductEdge;
const { naceleEntryId } = edge;

const [firstProduct] = await client.products({ maxReturnedEntries: 5 });
const { nacelleEntryId } = firstProduct as Product;

Product collections

The productCollections method accepts an object with the following properties to define the options of the query

  • nacelleEntryIds - (string[], Optional) An array of productCollection.nacelleEntryIds, which are unique IDs assigned to product collections by Nacelle.

  • handles - (string[], Optional) An array of product collection handles.

  • locale - (string, Optional, default: 'en-US') An IETF locale.

  • maxReturnedEntries - (number, Optional) Sets an upper limit on the number of returned collections.

  • edgesToNodes - (boolean, Optional, default: true) Sets whether the method returns ProductCollection objects or ProductCollectionEdge objects. When false, ProductCollectionEdge objects are returned. ProductCollectionEdges have a cursor and node. The cursor value can be used for paginating; the node contains the collection data.

  • cursor - (string, Optional) Returned entries will come after this cursor value.

  • startAfterEntryId - (string, Optional) Returned entries will come after this specified ID. Uses deprecated productCollections Storefront API query. If you need to paginate requests, it is recommended to use thecursor values returned when edgesToNodes is false.

  • maxReturnedEntriesPerCollection - (number, Optional) The number of products to be queried for each collection returned

  • advancedOptions - (object, Optional)

    • entriesPerPage - (number, Optional) The SDK is configured to automatically request entries in batches. The number of entries it will attempt to request at a time can be optionally tuned using this parameter.

Product collections examples

// Get the first 5 product collections.
await client.productCollections({
  maxReturnedEntries: 5
});

// Get product collections by handles.
await client.productCollections({
  handles: ['collection-1', 'collection-2']
});

// Get product collections after a specified ID.
await client.productCollections({
  startAfterEntryId: 'someNacelleEntryId'
});

// Get the first 50 products for each collection
await client.productCollections({
  maxReturnedEntriesPerCollection: 50
})

// How to access products on a collection
const collections = await client.collections();
const { products, productConnection } = collections[0];

const { nacelleEntryId } = products[0]; // An array of type `Product`

const { pageInfo, edges } = productConnection;
const { cursor, node } = edges[0];
const { nacelleEntryId } = node;

Product collection entries

The productCollectionEntries method accepts an object with the following properties to define the options of the query:

  • collectionEntryId - (string, Optional) The nacelleEntryId for the collection's products you want to query. Either collectionEntryId or handle is required.

  • handle - (string[], Optional) The handle of the collection's products you want to query.

  • locale - (string, Optional, default: 'en-US') An IETF locale.

  • maxReturnedEntries - (number, Optional) Sets an upper limit on the number of returned products.

  • edgesToNodes - (boolean, Optional, default: true) Sets whether the method returns Product objects or ProductEdge objects. When false, ProductEdge objects are returned. ProductEdges have a cursor and node. The cursor value can be used for paginating; the node contains the product data.

  • cursor - (string, Optional) Returned entries will come after this cursor value.

  • startAfterEntryId - (string, Optional) Returned entries will come after this specified ID. Uses deprecated productCollections Storefront API query. If you need to paginate requests, it is recommended to use the cursor values returned when edgesToNodes is false.

  • advancedOptions - (object, Optional)

    • entriesPerPage - (number, Optional) The SDK is configured to automatically request entries in batches. The number of entries it will attempt to request at a time can be optionally tuned using this parameter.

Product collection entries examples

// Get all the products belonging to a collection with handle 'shoes'
await client.productCollectionEntries({
  handle: 'shoes',
  maxReturnedEntries: -1
});

// Get first 20 products belonging to a collection with handle 'hats'
await client.productCollectionEntries({
  handle: 'hats',
  maxReturnedEntries: 20
})

Content

The content method accepts an object with the following properties to define the options of the query:

  • nacelleEntryIds - (string[], Optional) An array of content.nacelleEntryIds, which are unique IDs assigned to individual content entries by Nacelle.

  • handles - (string[], Optional) An array of content handles.

  • locale - (string, Optional, default: 'en-US') An IETF locale.

  • maxReturnedEntries - (number, Optional) Sets an upper limit on the number of returned content entries.

  • edgesToNodes - (boolean, Optional, default: true) Sets whether the method returns Content objects or ContentEdge objects. When false, ContentEdge objects are returned. ContentEdges have a cursor and node. The cursor value can be used for paginating; the node contains the content data.

  • entryDepth - (number, Optional) Sets the maximum level of content resolution depth in content.fields. For more details, see Content Resolution.

  • cursor - (string, Optional) Returned entries will come after this cursor value.

  • startAfterEntryId - (string, Optional) Returned entries will come after this specified ID. Uses deprecated content Storefront API query. If you need to paginate requests, it is recommended to use the cursor values returned when edgesToNodes is false.

  • type - (string, Optional) Allows for querying by content type

  • advancedOptions - (object, Optional)

    • entriesPerPage - (number, Optional) The SDK is configured to automatically request entries in batches. The number of entries it will attempt to request at a time can be optionally tuned using this parameter.

Content examples

// Get the first 5 content entries.
await client.content({
  maxReturnedEntries: 5
});

// Get content by handles.
await client.content({
  handles: ['content-1', 'content-2']
});

// Get only articles
await client.content({ type: 'article' })

Navigation

The navigation method returns Navigation data. It has no required parameters. It accepts an optional params object with the following properties:

  • groupId - (string, Optional) The group ID is assigned to a navigation group in the Nacelle Dashboard.

Navigation examples

// Get all Navigation Groups
await client.navigation();

// Get a single Navigation Group
await client.navigation({
  groupId: 'footer'
});

Space properties

The spaceProperties method returns Space Properties data. It's called without any parameters.

// Get all Space Properties
await client.spaceProperties();

Custom GraphQL query

The query method submits GraphQL requests to the Nacelle Storefront GraphQL API. It accepts an object with the following properties:

  • query - (string, Required) A GraphQL query.
  • variables - (string, Optional) Stingified object containing any GraphQL variables used in the query.

Custom Graphql query example

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

const variables = JSON.stringify({
  filter: {
    handles: 'collection-1'
  }
});

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 two positional arguments, method and callback:

  • 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.

After examples

// 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.

Troubleshooting

  • Syntax errors may indicate that the arguments provided to a Storefront SDK method are not correctly structured. Ensure arguments are provided in an object with the properties listed in this document.

  • A Variable "$filter" got invalid value error occurs when the wrong data type is provided in the arguments of an SDK method. Make sure the values match the expected types described in this document.