npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@nacelle/shopify-checkout

v0.1.2

Published

A minimal Shopify checkout client for headless storefronts

Downloads

8,641

Readme

@nacelle/shopify-checkout

A minimal Shopify checkout client for headless storefronts.

npm version

Overview

@nacelle/shopify-checkout adds Shopify checkout functionality to headless commerce projects. While it's tailored to support the needs of Nacelle-powered storefronts, it's possible for any headless Shopify storefront to use this package by following the API described below.

Features

  • tiny, with zero dependencies
  • full TypeScript support
  • ships in tree-shakeable ESM, as well as UMD & IIFE formats for maximum portability
  • high code coverage

Usage

Install

npm i @nacelle/shopify-checkout

Prerequisites

To get started, you'll need:

Initializing the client

The checkout client can be initialized anywhere in your application. We recommend initializing it once. You can then import the initialized client wherever it's needed.

import createShopifyCheckoutClient from '@nacelle/shopify-checkout';

const checkoutClient = createShopifyCheckoutClient({
  storefrontCheckoutToken: '<your-storefront-api-token>',
  myshopifyDomain: '<your-shop-id>'
});

Common Types

When working with the checkout client, there are some common types that it will help to be familiar with:

| Type | Description | | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Metafield | A Metafield is an object that contains two properties: a key and a value, which both have string values. | | CartItem | A CartItem is an object with two required properties: variantId (a Shopify global ID) and a quantity (number). A CartItem may contain the optional property metafields (Metafield[]). | | ShopifyCheckout | A ShopifyCheckout is an object that contains the following properties: id (string), url (string) the address of the Shopify checkout, completed (boolean), lines (array) the line items in the checkout, discountApplications (array) the discounts being applied to the checkout. |

Examples of Common Types:

Metafield
{ key: 'forecast', value: 'sunshine' }
CartItem
{
  variantId: 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0VmFyaWFudC8xMjM0NQ==',
  quantity: 4
},
{
  variantId: 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0VmFyaWFudC85ODc2NQ==',
  quantity: 2,
  metafields: [
    { key: 'care_instructions', value: 'hand wash; drip dry' }
  ]
},

Checkout client API

The checkout client exposes two methods, get and process.

get({ id })

Retrieves an existing Shopify checkout.

Accepts: params - an object containing the id (string) of interest.

Returns: a ShopifyCheckout.

Example
const id = 'Z2lkOi8vc2hvcGlmeS9DaGVja291dC85OTg4Nzc/a2V5PTEyMzEyMw==';
const checkout = await checkoutClient.get({ id });

process(params)

Creates a new Shopify checkout, or updates an existing Shopify checkout.

Accepts: params (see examples below).

Returns: a ShopifyCheckout.

Creating a new Shopify checkout

| Parameter | Type | Required? | Description | | ------------ | --------------------- | --------- | ---------------------------------------------------------------------------------- | | cartItems | CartItem[] | ✅ | An array of line items. | | metafields | Metafield[] | ⛔️ | Corresponds to a Shopify Checkout's customAttributes. | | note | string | ⛔️ | The Shopify Checkout's note |

Example
// create a new checkout with checkout-level `customAttributes` and `note`
const checkout = await checkoutClient.process({
  cartItems: [
    {
      variantId: 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0VmFyaWFudC8xMjM0NQ==',
      quantity: 1
    }
  ],
  metafields: [{ key: 'gift_options', value: 'wrapped in gift paper' }],
  note: 'Thanks for taking care of the gift wrapping!'
});
Updating an existing Shopify checkout

| Parameter | Type | Required? | Description | | ------------ | --------------------- | ------------------ | ---------------------------------------------------------------------------------- | | id | string | ✅ | An existing Shopify checkout's global ID. | | cartItems | CartItem[] | (only if updating) | An array of line items. | | metafields | Metafield[] | (only if updating) | Corresponds to a Shopify Checkout's customAttributes. | | note | string | (only if updating) | The Shopify Checkout's note. |

Example
// Update an existing checkout's line items, `customAttributes`, and `note`
const checkout = await checkoutClient.process({
  id: 'Z2lkOi8vc2hvcGlmeS9DaGVja291dC85OTg4Nzc/a2V5PTEyMzEyMw==',
  cartItems: [
    {
      variantId: 'Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0VmFyaWFudC8xMjM0NQ==',
      quantity: 1,
      metafields: [{ key: 'engrave_text', value: 'i ❤️ headless commerce' }]
    }
  ],
  metafields: [{ key: 'gift_options', value: 'in box with bow' }],
  note: 'Please use a red ribbon for the bow, if possible :)'
});
Applying a discount to checkout

| Parameter | Type | Required? | Description | | -------------- | --------------------- | --------- | ------------------------------------------------------------ | | id | string | ✅ | An existing Shopify checkout's global ID. | | discountCode | string | ✅ | A discount code |

Example
// Apply a discount code to checkout
const checkout = await checkoutClient.discountApply({
  id: 'Z2lkOi8vc2hvcGlmeS9DaGVja291dC85OTg4Nzc/a2V5PTEyMzEyMw==',
  discountCode: 'BFCM'
});
Removing a discount from checkout

| Parameter | Type | Required? | Description | | --------- | --------------------- | --------- | ------------------------------------------------------------ | | id | string | ✅ | An existing Shopify checkout's global ID. |

Example
// Remove discount code from checkout
const checkout = await checkoutClient.discountRemove({
  id: 'Z2lkOi8vc2hvcGlmeS9DaGVja291dC85OTg4Nzc/a2V5PTEyMzEyMw=='
});
Making custom checkout queries to the Shopify Storefront API

| Parameter | Type | Required? | Description | | ----------- | --------------------- | --------- | ----------------------------------------------------- | | query | string | ✅ | A Shopify Storefront API query/mutation | | variables | object | ✅ | Variables for a Shopify Storefront API query/mutation |

Example
// Send any query/mutation to the Shopify Storefront API
const checkout = await checkoutClient.query({
  query: `
    mutation checkoutShippingAddressUpdateV2($checkoutId: ID!, $shippingAddress: MailingAddressInput!) {
      checkoutShippingAddressUpdateV2(checkoutId: $checkoutId, shippingAddress: $shippingAddress) {
        checkout {
          id
          webUrl
        }
        checkoutUserErrors {
          code
          fields
          message
        }
      }
    }
    `,
  variables: {
    checkoutId: checkoutData.id,
    shippingAddress: {
      address1: '123 smith street',
      city: 'Smith',
      country: 'USA',
      firstName: 'John',
      lastName: 'John'
    }
  }
});

Other example mutations from Shopify docs:

Advanced Usage

Using a custom fetchClient

By default, @nacelle/shopify-checkout makes GraphQL requests to Shopify's Storefront API with window.fetch. If window.fetch doesn't meet your project's requirements (e.g. if you need to support IE11), you can supply a fetchClient when initializing the checkout client. For example:

import createShopifyCheckoutClient from '@nacelle/shopify-checkout';
import isoFetch from 'isomorphic-unfetch';

const checkoutClient = createShopifyCheckoutClient({
  storefrontCheckoutToken: '<your-storefront-api-token>',
  myshopifyDomain: '<your-shop-id>',
  fetchClient: isoFetch
});

The only requirement of the fetchClient is that it implements the Fetch API (axios, for instance, won't work). We recommend checking out isomorphic-unfetch, cross-fetch, or similar.

Using a custom Shopify endpoint

If you'd prefer to specify a Shopify Storefront GraphQL API endpoint directly, without supplying a myshopifyDomain, you may do so by specifying a customEndpoint when initializing the checkout client. For example:

const checkoutClient = createShopifyCheckoutClient({
  storefrontCheckoutToken: '<your-storefront-api-token>',
  customEndpoint: '<your-storefront-api-endpoint>'
});