Contents

How to add a headless CMS to Spree Commerce

When managing content in Spree Commerce you hit the limits pretty fast. Especially when you want to create modern layouts with grids, sliders and teasers. In this tutorial I’ll show you how to add the component based headless CMS Storyblok to create product pages that are enriched with marketing content.

This will help you to offer editors the possibility to tell stories about the product while still maintaining the control of the layout to you as developer.

Prerequisites

Before beginning be sure to have Ruby on Rails and a Spree Commerce project running. If you don’t have a Storyblok space yet you can get one for free here. You can also download the code of this tutorial on Github.

  • Ruby on Rails
  • Spree Commerce
  • A Storyblok space

Install the Storyblok Client

Start with adding the Storyblok Ruby SDK to your Gemfile.

Gemfile
gem 'storyblok'

Execute bundle install after adding the gem.

Add the View Helpers

Add the following three view helpers to app/helpers/application_helper.rb to have easy access to the Storyblok client and the Storyblok’s Javascript Bridge. Be sure to exchange YOUR_STORYBLOK_PREVIEW_TOKEN with the token from the Storyblok dashboard.

app/helpers/application_helper.rb
module ApplicationHelper
  def storyblok_preview_token
    'YOUR_STORYBLOK_PREVIEW_TOKEN'
  end

  def storyblok_js_bridge
    "<script src=\"//app.storyblok.com/f/storyblok-latest.js?t=#{storyblok_preview_token}&autoReload=1\"></script>"
  end

  def get_story_by_slug slug
  	begin
  	  client = Storyblok::Client.new(token: storyblok_preview_token)
  	  return client.story(slug)
  	rescue RestClient::NotFound
      return nil
  	end
  end
end

Open the Spree Commerce template used to show the product detail page (app/views/spree/products/show.html.erb) and add a partial at the end of the file.

app/views/spree/products/show.html.erb
...

<%= render partial: 'cms/components/product' %>

Create the CMS Components

To fetch and render the content from Storyblok’s Api add folder cms/components and create the file _product.html.erb. The code below shows that we are getting the CMS content based on the product slug.

app/views/cms/components/_product.html.erb
<% content = get_story_by_slug('products/' + @product.slug) %>

<% if content %>
  <% content['data']['story']['content']['body'].each do |blok| %>
    <%= render partial: "cms/components/#{blok['component']}", locals: { blok: blok } %>
  <% end %>
<% end %>

<%=raw storyblok_js_bridge %>

Create a Content Item in Storyblok

Time to connect your storefront to Storyblok’s visual editing interface. Following the steps required to get Spree running inside Storyblok.

  1. Create a empty Space at app.storyblok.com.
  2. Create the folder products.
  3. Create the content item of your product. If you are using Spree’s demo shop you can define ruby-on-rails-tote as slug.
  4. Click on the address bar to change the environment to http://localhost:3000 if you are running Spree on the default port.
  5. Allow Storyblok to include your Spree storefront by including X-Frame-Options to the application config at app/config/application.rb.

    config.action_dispatch.default_headers = {
      'X-Frame-Options' => 'ALLOW-FROM https://app.storyblok.com/'
    }
    

After the steps above you should see the product detail page. Click now on “Compose” to switch to the compose mode.

Add your first Block

When you are in the compose mode add a new block by clicking on the “Add block” button and writing “section” into the search field. The schema definition will appear. Add the fields image, description and headline like in the screenshot bellow.

After you saved the section in Storyblok it’s time to create the template in your Ruby on Rails project. Add the file _section.html.erb with follwing code to the folder app/views/cms/components.

app/views/cms/components/_section.html.erb
<%=raw blok['_editable'] %>
<div class="row">
  <div class="col-sm-6">
    <h2><%= blok['headline'] %></h2>
    <div>
      <%= blok['description'] %>
    </div>
  </div>
  <div class="col-sm-6">
    <% if !blok['image'].blank? %>
      <img class="img-responsive" src="<%= blok['image'] %>" />
    <% end %>
  </div>
</div>

Notice the blok[‘_editable‘] attribute. This attribute is empty in the published version of the content item and filled with a HTML comment when receiving the draft version. This helps Storyblok’s Javascript bridge to identify editable blocks.

Endresult

At the end you should have a clickable block on your product page. Add a couple more components and your editors will be able to create content rich product pages like you know from www.apple.com/iphone-se/

Extra: How to add a Blog to Spree Commerce?

To setup a blog structure with Storyblok and Spree Commerce I recommend you to read the following two tutorials which will show you how to setup a controller and the necessary content types:

Conclusion

It’s incredibly easy to extend product pages with a flexible block based marketing content using Spree Commerce and Storyblok. But the technique described in this tutorial is not limited to Spree Commerce. You integrate a headless CMS like Storyblok also to other e-commerce systems like Magento, Opencart and even Shopify.

ResourceLink
Github repository of this Tutorialgithub.com/storyblok/spree-commerce-tutorial
Ruby on RailsRuby on Rails
Storyblok AppStoryblok

More to read...

About the author

Alexander Feiglstorfer

Alexander Feiglstorfer

Passionate developer and always in search of the most effective way to resolve a problem. After working 13 years for agencies and SaaS companies using almost every CMS out there he founded Storyblok to solve the problem of being forced to a technology, proprietary template languages and the plugin hell of monolithic systems.