Create Custom BigCommerce Templates with React in Stencil

Patrick Puente
BigCommerce Developer Blog
8 min readOct 31, 2019

As a Solution Architect at BigCommerce, I meet clients and agencies who want to incorporate React into their Stencil theme. Maybe you want to utilize your existing component library, or React is just your preferred front-end framework. In some cases, those projects end up going the headless route, where the website’s front-end lives outside of BigCommerce, and integrates with BigCommerce APIs to manage catalog data, customer accounts, promotions, carts, and even checkout. Other times, we combine React with Stencil so that BigCommerce hosts the front-end. I’ve seen a few approaches to incorporating React into a Stencil theme, and each has its pros and cons. This article is intended to be a step by step guide to starting custom templates with React in a Stencil theme in a way that is scalable and reusable.

Table of Contents

  1. Introduction
    - What is a custom Template?
    - What is React?
  2. The Approach
  3. Procedure
    - Prerequisites
    - Install Dependencies
    - Configure Webpack
    - Create a Custom Template
    - Create a Custom Module
    - Map the Custom Module to the Custom Template
  4. Result

What is a custom template?

By default, all pages of a given type use the same template file in a Stencil theme. Examples of page types include

  • Product Details Pages
  • Category Pages (product listing pages)
  • Brand Pages (product listing pages)
  • Web Pages (i.e. content pages)

It is possible to create a custom template to apply to a subset of pages of a particular type. For example, if a store needs to use a different layout for a particular subset of category pages so they can display content from an external source, the BigCommerce store can utilize custom templates from the Stencil theme for that subset of categories. In this article, I will demonstrate how to create a custom template for a category page that renders information about the page in a React component.

What is React?

React is one of the most popular front-end frameworks available today. It allows developers to build reusable components with self-contained state which can be composed into complex UIs. There are oodles of tutorials and examples of React available online, so I won’t spend a lot of time explaining it here. This article is intended for developers that are already familiar with the basic concepts of React. In this article, I will demonstrate how to create a React component that receives a context prop that contains information from Stencil about the category page, like the products it should display.

The Approach

This example leverages the pattern devised by sacr3dc0w to map a custom template to a custom JavaScript module. In this case, the module extends the PageManager class and uses its onReady method to render React inside of an element in the custom template. The custom template will retrieve information from Stencil utilizing Handlebars, and inject that into a global variable called context that is accessible by the JavaScript module via the PageManager constructor. The JavaScript module in turn passes the page context to React as a prop.

In this example, the actual React component will simply display the text “Hello World” followed by the data from Stencil.

Procedure

Now the fun stuff…

Prerequisites

…Okay, almost. But first, let’s set up the environment. If you have already set up a Stencil development environment and cloned your theme, you can skip ahead to Install dependencies.

  • BigCommerce Store

If you do not already have a BigCommerce store, you can set up a trial at https://www.bigcommerce.com/essentials/.

  • Node and npm

The Stencil CLI runs in the Node runtime environment. BigCommerce currently recommends Node version 10.16 and provides instructions to install the recommended version of Node here.

  • Stencil CLI

Install Stencil CLI via npm:

npm install -g @bigcommerce/stencil-cli

For more information on installing Stencil CLI, see the BigCommerce documentation.

  • Cornerstone Theme

You can use this approach in any Stencil theme, but this example will utilize the reference implementation called Cornerstone. It’s good to create a folder to store your Stencil themes, and clone Cornerstone or another theme for each new project. For this example, I will assume you are cloning Cornerstone into a folder named react-stencil.

git clone https://github.com/bigcommerce/cornerstone react-stencil
cd react-stencil
npm install

After you clone the theme and install the base dependencies, you can initialize the theme with your store’s API credentials. Log into your BigCommerce store, then navigate to Advanced Settings > API Accounts. Click Create API Account > Create Stencil-CLI Token. Copy the quickstart command, paste it into your terminal, and press enter three times. The command should look something like this:

stencil init --url https://<your-domain> --token <api-token>

For more information on cloning and initializing the Cornerstone theme see the BigCommerce documentation.

Install Dependencies

Add React, ReactDOM, and the React preset for Babel to your project.

npm install react react-dom @babel/preset-react

Configure Webpack

In webpack.common.js, add ['@babel/preset-react'] to modules.rules[0].use.options.presets. This is the presets array from the example:

presets: [
['@babel/preset-env', {
loose: true,
modules: false,
useBuiltIns: 'usage',
targets: '> 1%, last 2 versions, Firefox ESR',
}],
['@babel/preset-react'],
],

See the whole webpack.common.js on github here.

Optional: Add CSS loader
While it’s not required for this example, you will want to also add loaders for CSS files if you intend to add CSS files to your React app, or plan to use a component library that includes CSS modules like React Toolbox. These steps have been tested for React Toolbox:

1. Install Dependencies:
npm install style-loader css-loader

2. Add the following to the modules.rules array in webpack.common.js:

{
test: /\.css/,
loader:[ 'style-loader', 'css-loader' ]
}

Create a Custom Template

This article will demonstrate creating a custom Category template, but you can use the same approach for custom Product, Brand, or Web Page templates as well. Start by creating a new folder at templates/custom/category.

  • Windows:
mkdir templates\pages\custom\category
  • Mac/Linux
mkdir templates/pages/custom/category

The resulting structure of the templates folder should look like this:

templates
∟ components
∟ layout
∟ pages

∟ custom
∟ category

Copy templates\pages\category.html to the new folder and rename it react-demo.html:

Windows:

copy templates\pages\category.html templates\pages\custom\category\react-demo.html

Mac/Linux:

cp templates/pages/category.html templates/custom/category/react-demo.html

In react-demo.html replace everything between {{#partial "page"}}and {{/partial}} with:

{{inject "category" category}}
<div id="root">Hello World!</div>

The {{inject}} helper adds the category object from Stencil to the page context your custom JavaScript module will be able to access.

The <div> will display “Hello World!” so you can test to validate the template mapping. It will also serve as the mounting point for React

react-demo.html

See react-demo.html on github here.

Map the Custom Template in .stencil

In the project’s .stencil file, you will map the custom page template file to a category page URL. This is so you can render your custom page template in your local environment. Once the theme is applied to a store, you will need to map specific categories to the template to use your custom template on the live site. For more on applying custom templates, see the BigCommerce documentation.

If you prefer to simply change the default template and apply your template with React to every category, you can make the same changes to the existing templates\pages\category.html andassets\js\theme\category.jsfiles, then skip this mapping step.

Test the custom template

Confirm your template is mapped correctly by starting the local development server with Stencil CLI:

stencil start

Navigate to the mapped URL on localhost to ensure your template is rendered. For example: http://localhost:3000/shop-all/

You should see the global header and footer, and the text Hello World! in the main content area:

The custom template is works!

If you prefer to replace the entire page, including the global header and footer, with your React app, consider creating a custom layout file that removes the header and footer. Learn more about Stencil template composition in the BigCommerce documentation.

Create a Custom Module

The React app will live in assets\js\theme\custom\react-demo.js. Start by creating the folder.

  • Windows:
mkdir assets\js\theme\custom
  • Mac/Linux:
mkdir assets/js/theme/custom

Then, create the file:

  • Windows:

Use File Explorer, or consider using this approach in PowerShell.

  • Mac/Linux
touch assets/js/theme/custom/react-demo.js

In react-demo.js, import React, ReactDOM, and PageManager:

import React from 'react'
import ReactDOM from 'react-dom'
import PageManager from '../page-manager'

In react-demo.js, create a simple HelloWorld component that displays its props:

const HelloWorld = (props) => (
<div>
<p>Hello World from React!</p>
<p>Here are my props:</p>
<pre>{JSON.stringify(props, null, 2)}</pre>
</div>
)

Note: The preconfigured rules for eslint in Cornestone do not play nice with JSX. You may choose to modify the eslint rules in .eslintrc. Alternatively, you can disable eslint for specific files by adding this comment to the first line of the file: /*eslint-disable*/

In react-demo.js, export a new child class that extends the PageManager class. This class is responsible for mounting the HelloWorld component in the div in the custom category template, and passing the page context to the component as a prop:

export default class ReactDemo extends PageManager {
onReady() {
const container = $('#root')[0]
ReactDOM.render(<HelloWorld context={this.context}/>, container)
}
}

See the whole thing here…

react-demo.js

…or on github here.

Map the Custom Module to the Custom Template

Thanks to sacr3dc0w’s blueprint for mapping custom template to javascript modules, all we need to do to load our module on the pages that render the custom template is to add a mapping to the customClasses object in assets\js\app.js. Since the value of context.templatein app.js may vary depending on the environment, the example maps the module to the value provided by both Windows and Mac/Linux environments:

customClasses declaration from app.js

See the full app.js on github here.

Result

When you visit the category page in your local environment, you should now see a custom category template that renders React, and has access to the category page context supplied by Stencil:

screenshot of the end result
It doesn’t look very exciting, but it’s got what you need to make an amazing experience on BigCommerce with React.

Notice how context.category includes information from Stencil needed to render a product listing page. You could use the {{inject}} helper in templates\pages\custom\category\react-demo.html to add additional information to the page context. Or, you could follow the same pattern to load custom React modules into product, brand, or web pages.

Now that you know how to build BigCommerce pages with React templates in Stencil, go make some more amazing BigCommerce themes!

--

--