good-idea / sane-shopify

MIT License
212 stars 15 forks source link

Sane Shopify

All Contributors

🚨 Heads up! This project is no longer in active development. See the official Sanity Connect for Shopify plugin instead! 🚨

All minor version changes (0.X.0) are likely to have breaking changes. If you are updating and have issues, see the alpha changelog below.

See this issue for the 1.0 roadmap.

This repo consists of several packages that connect Sanity and the Shopify Storefront API.

Curious? 🤔

If you want to be notified of updates, leave a comment in this issue.

Contributing

All contributions are welcome! Please open issues for any ideas for what you'd like this package to do. If you want to contribute to the project, see the Contributing docs.

What this project is

Sane Shopify was built after working around the limitations of the Shopify product & collection editor. Shopify has great e-commerce administration capabilities, but as a CMS, it's far behind solutions such as Sanity in terms of customization. Adding content beyond Shopify's defaults requires working with metafields, through 3rd-party apps or plugins. For example:

This project aims to solve these problems by using Sanity to extend Shopify's Products and Collections. It does this by:

This project does not:

Caveats


Installation & Setup

New setup starting with v0.11.0

In your Sanity installation, install the plugin: yarn add @sane-shopify/sanity-plugin. Once installed, add @sane-shopify/sanity-plugin to the list of plugins in sanity.json.

Add the Product and Collection documents to your schema:

// schema.js

import { saneShopify } from '@sane-shopify/sanity-plugin'

const saneShopifyConfig = {
  ... // optional. see "configuration" below
}

const saneShopifyTypes = saneShopify(saneShopifyConfig)

export default createSchema({
  name: 'default',
  types: schemaTypes.concat([
    ...saneShopifyTypes,
  ])
})

Webhooks

Version 0.11.0 introduces webhooks to keep your Sanity data in sync.

For convenience, there are "pre-packaged" webhooks set up for Mirco JS (if you use Next.js) or Lambdas (for AWS, Netlify).

See the @sane-shopfiy/server README for instructions on setting this up.

Usage

Sane-shopify fetches your product and collection data from Shopify's Storefront API, and stores up-to-date copies of this information within Sanity. This means you can query your Sanity endpoint directly for all of the data you need to display products and collections.

Collection & Product Documents

This plugin will add two document types to your schema: shopifyCollection and shopifyProduct.

shopifyCollection

The Collection document has:

shopifyProduct

The Product document has:

Extending Document and Objects

The shopifyCollection and shopifyProduct documents can be extended with custom fields or other standard Sanity configuration, such as custom previews or input components.

To set this up, create a configuration object and assign custom configuration to any of the following properties:

Example:

{
  collection: {
    // Shopify only allows a single image on collections. Here, we can add a gallery:
    fields: [
      {
        name: 'gallery',
        title: 'Gallery',
        type: 'array',
        of: [{ type: 'image' }]
      }
    ]
  },
  product: {
    fields: [
      // Shopify's HTML description input can get messy. Let's have our users enter the descriptions using Sanity's rich text instead.
      {
        name: 'description',
        title: 'Description',
        type: 'array',
        of: [{ type: 'block' }]
      },

      // Our users won't be editing fields on product variants. Let's hide that field. This will merge the "hidden" value into the sane-shoipfy defaults:
      {
        name: 'variants',
        hidden: true
      }
    ]
  },
  productVariant: {
    // Not adding anything here!
  },
  productOption: {
    // Let's make the preview for option list items a little more informative:
    preview: {
      select: {
        name: 'name',
        values: 'values'
      },
      prepare: (fields) => {
        const { name, values } = fields
        const subtitle = values.map((v) => v.value).join(' | ')
        return {
          title: name,
          subtitle
        }
      }
    }
  },
  productOptionValue: {
    // Our "Color" options will get a custom image swatch to use on the frontend

    fields: [
      {
        name: 'swatch',
        title: 'Color Swatch',
        type: 'image'
      }
    ]
  }
}

Connecting to Shopify

Set up a new app in Shopify with permissions to access the Storefront API. You'll need the Storefront Access Token (note that this is different from the Admin API key).

After you have installed the plugin and added the schema documents, open up Sanity. Click the new 🛍 Shopify tab in the header.

Enter your Shopify storefront name and your access token in the setup pane. Once this is set up, you can click the Sync button to import your collections and products.

Setting up Shopify webhooks

See the instructions in the @sane-shopify/server Readme

Working with the Cart

This plugin does not manage orders or customer carts. You will need to use Shopify's storefront API (or another solution) to do this. But, the sanity documents will include all of the product & variant IDs you need.

Debugging

If you are experiencing issues or errors, you can get detailed logging by setting the DEBUG variable - either as an environment variable (for webhooks & server-side) or as a localStorage variable.

Browser: In your console, enter window.localStorage.debug = 'sane-shopify:*' Server: Set an environment variable in your script (if working locally), i.e. DEBUG=sane-shopify:* yarn start, or add a DEBUG environment variable to your hosting environment.

Scopes:

Alpha Changelog

0.24.0 🚨 BREAKING CHANGES

Shopify is deprecating the 2020-10 GraphQL API, so some changes were made to use the latest version, 2022-10. In previous versions of the API, were were able to query for all metafields on products and variants. In the latest version, you must ask for them specifically, given their namespace and key.

To configure this plugin to fetch metafields, a new shopifyConfig property has been added to the configuration. In the Sanity studio, use the configuration pane to add these values.

0.23.3

Oops, this version was meant to be published as 0.24.0. Please use 0.23.2 or 0.24 instead

Oops, this version was meant to be published as 0.24.0. Please use 0.23.2 or 0.24.0 instead.

0.20.0

The config for @sane-shopify/server has changed. onError is now part of the main config object. Instead of createWebhooks({ config, onError }), do createWebhooks(config). See the @sane-shopify/server README

Source data now includes shopify media. Thanks @liqueflies for adding this!

0.11.0

@sane-shopify/server now exports functions that can be used to handle Shopify's webhooks.

0.10.1

The plugin now marks products that are no longer in the Shopify catalogue as archived on their corresponding sanity documents. Relationships that no longer exist in Shopify are also removed.

0.9.0

Fixes setup flow

0.8.0

This release contains several breaking changes.

New features:

Migrating from 0.7.x

0.7.0

New features:

Migrating from 0.6.x

@sane-shopify/sanity-plugin now exports one more function, createProductVariant. Use it the same as the other exports - see the example in the usage instructions above.

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Joseph Thomas

📖 💻 ⚠️

Graham Lipsman

💻

James Homer

💻

Richard Cooke

📖

Lorenzo Girardi

💻

agonsgd

🐛

Synim

🐛

blaine oneill

💻

This project follows the all-contributors specification. Contributions of any kind welcome!