Migration Guide
This document provides a set of guidelines for migrating from v0.7 of the JS Buy SDK to v1 of the JS Buy SDK which uses Shopify's GraphQL-based Storefront API.
Table of Contents
Installation
With Yarn:
yarn add shopify-buy
With NPM:
Remove the old version, then
npm install shopify-buy
Updated Functions and Classes
Initialization
Rather than using a static function to create the client (ShopifyBuy.buildClient()
), v1 exposes the Client
(previously ShopClient
) and a Config
class for the Client
directly. An instance of Client
can be created like so:
import Client from 'shopify-buy';
const client = Client.buildClient({
domain: 'your-shop-name.myshopify.com',
storefrontAccessToken: 'your-storefront-access-token'
});
Fetching Products and Collections
The functions for fetching products and collections are mostly the same. Major differences are:
-
The v1 functions take in a
Storefront ID
for fetching a product or collection by ID. AStorefront ID
can be found under the retrieving IDs section of the Storefront API docs. Getting Started Guide for the Storefront API. -
Collections can be fetched with products using
collection.fetchWithProducts(id)
(fetches a single collection with associated products) andcollection.fetchAllWithProducts()
(fetches a page of collections with their associated products).
const collectionId = 'Z2lkOi8vc2hvcGlmeS9Db2xsZWN0aW9uLzI1NzY5NzczMQ=='
// Use the built-in function
client.collection.fetchWithProducts(collectionId).then((collection) => {
console.log(collection); // Collection with all default fields and products with all default fields.
console.log(collection.products); // Products on the collection
});
product.fetchQuery()
andcollection.fetchQuery()
query different fields and take an optionalquery
argument. See the product connection field and collection connection field docs in the storefront API for more details.
v0:
client.fetchQueryProducts({collection_id: '336903494', tag: ['hats']}).then((products) => {
console.log(products); // An array of products in collection '336903494' having the tag 'hats'
});
v1:
const query = {
query: 'updated_at:>="2016-09-25T21:31:33"',
sortBy: 'title'
};
client.product.fetchQuery(query).then((products) => {
console.log(products); // An array of products updated after 2016-09-25T21:31:33
// and sorted in ascending order by title.
});
Carts/Checkouts
Carts are replaced with checkouts. Like the fetch functions, all checkout functions take an optional query
argument that specifies fields to return on the checkout.
fetchRecentCart()
, updateModel()
, and clearLineItems()
have been removed. checkoutUrl
has been renamed to webUrl
.
Creating a Checkout
To create a checkout, use checkout.create()
. You are responsible for capturing the ID of the checkout for later usage. If you would like to persist the checkout between sessions, store the ID in a cookie or localStorage.
v0:
client.createCart().then((cart) => {
console.log(cart); // Empty cart
});
v1:
client.checkout.create().then((checkout) => {
console.log(checkout); // Empty checkout
console.log(checkout.id); // The ID of the checkout. Store this for later usage.
});
The checkout can also be initialized with fields like line items and a shipping address. See the API reference for more details.
Fetching a Checkout
To fetch a checkout, use fetchCheckout()
.
v0:
client.fetchRecentCart().then((cart) => {
console.log(cart); // Most recently created cart
});
v1:
client.checkout.create().then((checkout) => {
localStorage.setItem('checkoutId', checkout.id); // Store the ID in localStorage
});
// In another session:
const checkoutId = localStorage.getItem('checkoutId');
client.checkout.fetch(checkoutId).then((checkout) => {
console.log(checkout); // The retrieved checkout
});
v0:
client.fetchCart('shopify-buy.1459804699118.2').then(cart => {
console.log(cart); // The retrieved cart
});
v1:
const checkoutId = 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0SW1hZ2UvMTgyMTc3ODc1OTI='; // ID from a previous checkout.create call
client.checkout.fetch(checkoutId).then((checkout) => {
console.log(checkout); // The retrieved checkout
});
Modifying an Existing Checkout
The functions to modify a checkout are on Client
rather than CartModel
.
Adding Line Items
To add line items to a checkout, use addLineItems()
(previously createLineItemsFromVariants()
). Similar to the checkout's ID, you are responsible for storing line item IDs for updates and removals.
v0:
cart.createLineItemsFromVariants({variant: variantObject1, quantity: 5}, {variant: variantObject2, quantity: 2}).then((cart) => {
console.log(cart); // Cart with two additional line items
});
v1:
const checkoutId = 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0SW1hZ2UvMTgyMTc3ODc1OTI='; // ID from a previous checkout.create call
const lineItems = [
{variantId: 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0VmFyaWFudC8yNTYwMjIzNTk3Ng==', quantity: 5},
// Line items can also have additional custom attributes
{
variantId: 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0VmFyaWFudC8yNTYwMjIzNjA0MA==',
quantity: 2,
customAttributes: {'key': 'attributeKey', 'value': 'attributeValue'}
}
];
client.checkout.addLineItems(checkoutId, lineItems).then((checkout) => {
console.log(checkout); // Checkout with two additional line items
console.log(checkout.lineItems) // Line items on the checkout
});
Updating Line Items
To update line items on a checkout, use updateLineItems()
.
v0:
const lineItemId = 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0Lzc4NTc5ODkzODQ=';
const quantity = 1;
cart.updateLineItem(lineItemId, quantity).then((cart) => {
console.log(cart); // Cart with a line item quantity updated to 1
});
v1:
const checkoutId = 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0SW1hZ2UvMTgyMTc3ODc1OTI='; // ID from a previous checkout.create call
const lineItemId = 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0Lzc4NTc5ODkzODQ=';
const lineItems = [
{id: lineItemId, quantity: 1}
];
client.checkout.updateLineItems(checkoutId, lineItems).then((checkout) => {
console.log(checkout); // Checkout with a line item quantity updated to 1
console.log(checkout.lineItems) // Line items on the checkout
});
Removing Line Items
To remove line items on a checkout, use removeLineItems()
.
v0:
const lineItemId = 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0Lzc4NTc5ODkzODQ=';
cart.removeLineItem(lineItemId).then((cart) => {
console.log(cart); // Cart with a line item removed
});
v1:
const checkoutId = 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0SW1hZ2UvMTgyMTc3ODc1OTI='; // ID from a previous checkout.create call
const lineItemIds = [
'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0Lzc4NTc5ODkzODQ='
];
client.checkout.removeLineItems(checkoutId, lineItemIds).then((checkout) => {
console.log(checkout); // Checkout with a line item removed
console.log(checkout.lineItems) // Line items on the checkout
});
Pagination
Most models that are part of a paginated set (products, products on collections,
collections) are not fetched in their entirety. However, because we're using
GraphQL, and we're compliant with the Relay specification, all of these models
may be paginated using the underlying GraphQL Client. This functionality didn't
really exist in a clean way under v0
.
Examples
Paginating products on a shop.
let productList;
client.products.fetchAll().then((products) => {
productList = products;
});
// Do some stuff, and later:
client.fetchNextPage(productList).then((nextPageOfProducts) => {
// Do some other stuff
});
Paginating products on within a collection.
let productsForCollection;
client.collection.fetchWithProducts(collectionId).then((collection) => {
productsForCollection = collection.products;
});
// Do some stuff, and later:
client.fetchNextPage(productsForCollection).then((nextPageOfProducts) => {
// Do some other stuff
});
Paginating collections
let collectionList;
client.collection.fetchAll().then((collections) => {
collectionList = collections;
});
// Do some stuff, and later:
client.fetchNextPage(collectionList).then((nextPageOfCollections) => {
// Do some other stuff
});