This is a demo site built by Kevin Green. The products you find on this test site are from sites I've worked on. If you're interested in purchasing anything for real I link out to the real sites on the product landing pages!

Shopify Configuration

We use Shopify to handle commerce things like: products, inventory, customers, checkout, taxes etc... For the sake of our headless experience we have need of some specific configurations. In the Midway repository we only include a single file for Shopify, the theme.liquid. The reasoning for this is because we need to set up redirects from the Shopify experience.

Handling Shopify Customers

In order to enable accounts in our headless experience we need to redirect the default Shopify account functionality to our headless site. This is because we can't control the routing of the account activation, reset, or password resets from a Shopify environment. At the time of writing this we still need to implement this redirect hack to allow our headless environment to be fully functional. This is because the emails that go out from inside a Shopify experience are have an integrated URL that points to the integrated default domain in your Shopify configuration. We recommend that the Shopify checkout/experience live in a nested subdomain of your main site, for example: This will allow for a more seamless customer experience, instead of something like being your checkout url.

Steps to configuring Shopify store for headless accounts:

  1. Create a subdomain route for the store and make it your default domain.
  2. Ensure the Shopify client in your codebase talks to the sudomain route so your cart weburl is the subdomain route.
  3. Update your theme.liquid with a redirect script listed below.

Create an account/ route in your experience (you can find all the account related components in Midway in the auth/ directory inside the components.

Place the following code at the top of your theme.liquid file:

var l = window.location

if (/^\/a\//.test(l.pathname)) {
// do nothing
} else {
var href = ''
if (l.pathname) href += '/' + l.pathname
if (l.has) href += l.hash
if ( href +=

href = href.replace('//', '/') = 'https://' + href

Understanding Accounts in Headless

You will also need to make sure accounts are enabled on your Shopify instance. They should not be required, but optional. This will allow people to register/activate accounts.

In the Gatsby instance, assuming everything is setup, you should be able to create an account in the Shopify instance. From there everything else is business as usual. However customers going through a more traditional flow, like making a purchase and having an account created that way you'll need to follow some additional steps.

Shopify does not necessarily automatically send out invite emails for accounts created in headless environments. As a result you will need to use a Bulk invite plugin. These plugins let you set up intervals for inviting users into the system. Once that email comes from Shopify the customer will be directed to the Shopify instance with an activate route. This route will redirect to your experience with the redirect you set up above. From there they can enter in a password and create their account.

Shopify Product Sync

We also need to get our products into Sanity. While this isn't a 100% required it's one of the underlying reasons for using Sanity as a CMS in combination with your Shopify experience. We'll connect the Shopify products directly into Sanity so that we can extend them, add modules, customize variants, etc. The applications to extending your shopping experience start with syncing the basic Shopify product structure into Sanity.

Given our current example, we'll be using Netlify Functions. For anyone rolling your own the only thing you will need to do is change the route you are pointing the sync to.

I will only cover loosely what is going on here, please find the entire shopify-sync.tx file here. This file lives in our functions directory in our Netlify instance. You'll notice this function is actually a capture, we put it at the end of a webhook to accept data, and then transport it into our Sanity instance. We're fetching our environment variables specifically from Netlify running netlify dev. We are parsing the product and saving it to a Product type that we have configured in Sanity. We are then checking for nested variants and saving that to a Product Variant type in Sanity. We do this for a number of reason, allowing us to extend variant specific data, ability to associate variants to other products (like bundles), or simply allowing us to create variant cards on the frontend for direct quick adds.

Configuring your Webhooks to talk to Sanity

Assuming you have no questions about the actual Sync file, we'll need to configure Shopify to actually push data into Sanity.

In Shopify navigate to the following area:


You'll see you have the ability to create webhooks, we're going to want to create 3 webhooks: Product creation, Product update, & Product delete. Set the format to JSON, and then specify the URL pointing to the above Shopify sync file. For anyone more experienced you can also point it to an ngrok on your local machine for faster debugging/testing. In the case of our working example my url route is:

If you are running locally you should be able to see data logging in your console. Additionally saving a product in your Shopify if configured correctly should save a product into your Sanity instance.

From there you'll want to ensure your Shopify Products have the following:

  • Sku
  • Variants
  • Inventory
  • Pricing
  • Images associated to every Variant (for building our cart object, emails)