Building a Shopify Powered Blog with Contentful Webhooks and Micro

Kevin Green
The Couch
Published in
9 min readDec 11, 2017

Today we’re going to be hooking up a Contentful blog into a Shopify experience. This is by no means a beginner article but I’ll do my best to make it easy to follow. You should be familiar with both Contentful and Shopify, as well as have a good understanding of Es6 Javascript, but not entirely required to follow along (this could also pretty easily be swapped with Wordpress JSON API, Prismic, and other headless options).

What we’re using

Micro — Microservice framework that will be listening to webhooks
Now — Hosting platform for our microservice
Contentful Webhooks — sending data to our Micro service
Contentful NPM Package — Cleaning and parsing our data
Shopify Node API — Sending our cleaned up data back to Shopify
Ngork — For mapping localhost to an accessible web endpoint

While that might seem like a lot of moving pieces it’s actually really nice. The way I’ve hooked this up in the past is by creating unique identifiers that talk back and forth to each other. For example, I would use a slug on Shopify as the unique identifier on Contentful and pull the data into the frontend by querying that on Shopify.

'/blogs/passport/:slug': ({ slug }) => {
const cached = stories.get(slug)
if (cached) {
return true
}
return api.getEntries({
content_type: 'passports',
'fields.slug': slug,
include: 8
}).then(({ items }) => {
stories.set(slug, items[0].fields)
stories.emit('updated')
return true
})
}

This works fine as long as that information is kept updated and sync’d. The benefit of doing the additional webhook configuring is that we get a more streamlined content flow. It also means we don’t have to fetch data on Shopify anymore, instead we’ll save the data to Shopify only when it’s updated directly into the body_html so that we have access to all of our pretty content without needing any client side javascript on the Shopify end.

The Basics

Before we go too deep let’s do some initial setup, and talk about some conventions we’ll be following to make this all work.

Set up your Shopify Blog
Before we even set up our API/Microservices lets hop into Shopify and lay down the foundation. You’ll need to navigate to your Admin → Online Store → Blogs. From there you can create a blog and name it whatever you like, once we create it you’ll notice an ID in the URL slug. We’re going to need that later on to save to our config, but we can get it later.

Now that you have a blog let’s create your first post, the title and contents don’t really matter since we’ll be managing all of that content in Contentful you can fill it up with gibberish. I’d also go ahead and set it to hidden for now since we’ll be managing it’s publish status via Contentful as well.

Let’s not worry about styling/theming or any of that just yet, our goal is to get the content from Contentful into Shopify for now, worry about making it pretty later.

Set up your Contentful CMS
I was fortunate enough to have a really talented UX person on our Team (Abby), set up our initial structure for creating all of our content in Contentful. I’ll give a really short rundown of how we did it and include 2 modules (after all if we don’t make flexible content types there’s really no point in over engineering the blogs!)

If you’ve never set up Contenful this might all sound crazy and you might need to run through some getting started guides on their end.

Steps

  • Create a content model
  • In that model define the basics, Title, Published At, Featured Image, Author, Article Id (this one is really important and should be required), and then also create a field called Content Modules and make it a reference type with many:
  • Create your unique module content types, for the purpose of this example we’re going with two really simple modules, one will be a text module that is used for entering general text in a WYSIWYG editor, so when you create this one set it’s text type to Long Text. Then create another module for handling an image (for the purpose of this exercise let’s imagine the image in the design spans the full width sort of like how Medium does it). This can be a single media upload to keep it simple.
  • Once you create your modules (you can create more than 2 if you want go nuts) you’ll need to go back to the content model for the actual articles and edit the Content Modules we created. Hit Settings → Validations. Check off the accept only specific entry type and select the modules you just created, this will allow us to build out really robust blog posts that the client can manage without needing to be a developer :).

Creating a post in Contentful
We’re going to skip this for right now, because we want to set up the webhook and everything else first so that we can actually post our data directly to Shopify, so we’ll do this a little later.

Setting up our Microservice

I have a repo already set up that you guys can reference, but it’s actually a full working example of a blog I’m using now which I will get into later. For now we can start with building the foundation.

Hop into terminal and init a new project: npm init — set up your name/license ect.

npm i micro micro-post contentful marked shopify-api-node --save

We’re going to be using micro-post which is specifically built to handle post requests which is what our contentful webhook does; shopify-api-node for pushing data into Shopify via our webhook; marked for converting our contentful markdown content into html.

Your package.json should look something like this:

Next let’s create our simplest index.js (no data manipulation or anything like that yet)

Now we can run our app via terminal npm run micro. Now that we have the app running we need to set up ngrok so that we can tell Contentful to push data to our local environment.

npm i ngrok -g

Now in a new terminal window with your micro service still running (assuming we’re running it on port 3000), type into your terminal:

ngrok http 3000

This will spin up a ngrok endpoint which you can link in your Contentful settings. Now hop back into Contentful and under space settings select Webhooks.

Basic configuration for webhooks and contentful

You’ll see the ngrok url pasted above, you can name the Webhook whatever you would like and be sure to set it to listen to at least publish on content types, we could get more advanced with unpublish/delete ect. but I leave that up to y’all.

Next the moment we’ve all been waiting for, go create your first post in the blog content type you set up earlier. After publishing the post you should see a successful post in your ngrok console as well as the contents of the request posted in your micro console (via our parsed console log).

🎉 🎉 🎉 🎉

Okay let’s take a second and look at our accomplishments.

  • We set up a shopify default blog
  • We built a Content type in Contentful for handling our advanced blogging needs
  • We set up a micro server for accepting webhooks from Contentful
  • We set up ngrok for handling local webhook development (we’ll switch this to a now endpoint when we’re production ready)
  • We’re listening to webhook data from Contentful in our Micro instance and logging it to the console

~~Hell yeah~~

Time to get Jazzy — Cleaning the data and pushing to Shopify

So that initial parsed data we just console logged is a really good step in the right direction. However the way Contenful provides data from the Webhook isn’t as robust as we’ll need. One of the most powerful things about Contentful is it’s ability to nest content models, which is exactly what we did for our referenced Content Modules. In order to retrieve nested data structures we have to use the Content Delivery NPM package which we already installed above. So let’s extend how we’re fetching our data.

First create a little wrapper for the Contentful API:

Now for our data fetch hook up:

You’ll notice above in the getEntries request we use a param include this allows us to get 8 levels of nested content, this is probably over kill for this situation but you can request up to 10 levels of nested content (the more you know).

Lastly let’s modify our index.js to include this new request:

Above I’m doing a simple switch statement depending on the type of Webhook data we’re receiving it will handle the data in different ways. I have my contentType set in Contentful to be blog, you might have something else, or if you didn’t set one it will look like a unique identifier string. Now if we go back into Contentful and make an edit on our blog post we should see a new log to our console with a little bit more data, we’ll also have access to those content modules and the data inside of them.

Little back stepping then Shopify fun~

I also set up a config.js, this is where we store our app configs, you can use environment variables or services like torus/whatever’s your jam, but if you’re wondering heres the basic structure I’ve got right now:

Alright now that we’ve got our data in depth let’s push what we’ve got to Shopify! I’ll talk a bit about how I loop through the content modules after that.

First let’s set up our wrapper:

Now let’s modify our blog.js to send our data into Shopify.

So a few notes on the above, you’ll notice the buildBlogPost function, I’ll be showing you how I’ve got that set up in a second; this returns a template literal string that we push into the body_html of the Shopify API which lets us inject HTML into our Shopify WYSIWYG editor.

You’ll also notice the syntax for updating our Blog post, we’re currently relying on this webhook to update and not create, the reason for this is because we can’t manipulate data back into Contentful. Because we need to send down an articleId to make updates to existing posts it means we have to create the empty shell of an article in Shopify first. Which I mentioned earlier.

URL structure in Shopify Admin

You noticed in my Config that I store the blogId since that’s not changing (unless you have multiple blogs on your store), and the articleId above is what we have to include in our request and push to Shopify (this should be a field in your Contentful content model).

Almost there. We’ve now got data pushing into Shopify, for those of you with a little more experience this should be all you need to finish up/extend as much as you’d like. For anyone curious I’ll post a simplified version of what my buildBlogPosts looks like.

The above builds our basic Article layout structure, and then loops through all of our content modules and sends them down to our renderModules file. This file then checks what type of content the module is and renders the appropriate module type.

If we have a relatively related content structure you should be all set to pull data from Contentful and push it into Shopify. For a more robust and work in progress version of all this code (still extending it) you can check out the git repo:

Hosting your service

One last thing, we don’t want this to run locally forever so we have to set up some hosting, I find now to be one of the easiest ways to handle this, make sure you switch the node instance to at least 1 so that the server doesn’t spin down and don’t forget to switch your webhook endpoint in contentful. You can of course roll your own EC2 or use another service like Heroku.

Taking it even further

The above example is pretty basic, you could modify it to handle all your content within your Shopify site, things like home/about/simple pages. This would allow you to create a more robust and engaging web experience within your Shopify build.

What about Shopify sections?

I know some of you might be thinking why not just use Shopify sections. The simple answer is Shopify sections still don’t apply to the entire Shopify architecture. This is especially true of Products and Blog posts, so we have to build our own means of extending the Shopify experience.

Enjoy ~

--

--