Adding npm Packages to a Theme

Stencil’s architecture allows for organized customization using npm and React. In production, you can use these tools for stylizing seasonally themed products, temporary promotions, or event tickets. Below is a short tutorial on using npm and React to customize your Stencil theme.

In this example, we’ll be making a drawer that sends a coupon code to the customer’s email using Material UI’s React framework. The resulting customization will look like the following:

Image of Coupon Drawer example


  • Stencil CLI installed
  • BigCommerce store
  • Cornerstone Stencil theme with npm installed
  • Knowledge of HTML and JavaScript

To set up a BigCommerce store, see Creating a Trial Store.

Installing React and npm packages

To build this customization, complete the instructions in the following sections.

Install dependencies

For this example, we’ll be using packages from Material-UI. These components require certain modules.

Navigate into the root Cornerstone theme folder, then install the following npm packages.

# navigate into theme dir
cd ~/path/to/theme/dir

# install dependencies
npm install --save-dev @material-ui/core react react-dom babel-plugin-transform-object-assign @babel/preset-react

Update webpack.common.js

Updatewebpack.common.js with the new presets and plugins.

plugins: [
presets: [
    ['@babel/preset-env', {
    }], '@babel/react',

Create components

In the following steps, we’ll be adding React components to assemble our coupon drawer.

  1. Navigate to the ./assets/js folder.
  2. Create a /components folder within the /js folder.
  3. Navigate into the /components folder.
  4. Create a CouponDrawer.js file.
  5. Copy the following code into the file:
import React from 'react';
import Drawer from '@material-ui/core/Drawer';
import Button from '@material-ui/core/Button';
import VerticalStepper from './VerticalStepper';

export default function CouponDrawer() {
  const [state, setState] = React.useState({
    right: false,

  const toggleDrawer = (side, open) => event => {
    if (event.type === 'keydown' && (event.key === 'Tab' || event.key === 'Shift')) {

    setState({ ...state, [side]: open });

  return (
      <Button color="secondary" variant="contained" onClick={toggleDrawer('right', true)}>Click Here For A Coupon</Button>
      <Drawer anchor="right" open={state.right} onClose={toggleDrawer('right', false)}>
        <VerticalStepper />
  1. In the same /components folder, create a VerticalStepper.js file.
  2. Copy the following code into the file:
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Stepper from '@material-ui/core/Stepper';
import Step from '@material-ui/core/Step';
import StepLabel from '@material-ui/core/StepLabel';
import StepContent from '@material-ui/core/StepContent';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import TextField from './TextField';

const useStyles = makeStyles(theme => ({
  root: {
    width: '100%',
  button: {
    marginTop: theme.spacing(1),
    marginRight: theme.spacing(1),
  actionsContainer: {
    marginBottom: theme.spacing(2),
  resetContainer: {
    padding: theme.spacing(3),

function getSteps() {
  return ['Provide your email', 'Receive your coupon!'];

function getStepContent(step) {
  switch (step) {
    case 0:
      return `Please enter your email address:`;
    case 1:
      return `We have sent a coupon code to your email address.`;
      return `Unknown step`;

export default function VerticalLinearStepper() {
  const classes = useStyles();
  const [activeStep, setActiveStep] = React.useState(0);
  const steps = getSteps();

  const handleNext = () => {
    setActiveStep(prevActiveStep => prevActiveStep + 1);

  return (
    <div className={classes.root}>
      <Stepper activeStep={activeStep} orientation="vertical">
        {, index) => (
          <Step key={label}>
              {activeStep === 0 ? <TextField /> : null}
              <div className={classes.actionsContainer}>
                {activeStep === 0 && (
  1. In the same /components folder, create a TextField.js file.
  2. Copy the following code into the file:
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import TextField from '@material-ui/core/TextField';

const useStyles = makeStyles(theme => ({
  root: {
    '& > *': {
      margin: theme.spacing(1),
      width: 200,

export default function BasicTextFields() {
  const classes = useStyles();

  return (
    <form className={classes.root} noValidate autoComplete="off">
      <TextField id="standard-basic" label="" />

Import dependencies

  1. Import the React dependencies and the new CouponDrawer component we’ve created into assets/js/app.js:
__webpack_public_path__ = window.__webpack_public_path__; // eslint-disable-line

import Global from './theme/global';
import React from 'react';
import ReactDOM from 'react-dom';
import CouponDrawer from './components/CouponDrawer';
  1. At the bottom of the file, render the CouponDrawer component and assign it an id.
ReactDOM.render(<CouponDrawer />, document.querySelector('#coupondrawer'));

Add the CouponDrawer div to base.html

  1. Navigate to templates/layout/base.html.
  2. Add a new div element with our new id inside the body.
        <div id="coupondrawer"></div>

        {{> components/common/header }}
        {{> components/common/body }}
        {{> components/common/footer }}

        <script>window.__webpack_public_path__ = "{{cdn 'assets/dist/'}}";</script>
        <script src="{{cdn 'assets/dist/theme-bundle.main.js'}}"></script>
            {{!-- Exported in app.js --}}
            window.stencilBootstrap("{{page_type}}", {{jsContext}}).load();


Final product

View the finished product using the Stencil CLI command stencil start in the Cornerstone theme directory.

# move into theme dir
cd ~/path/to/theme/dir

# Preview store using Browsersync
stencil start

Open your browser and navigate to localhost:3000 to view your local storefront.

Note: This coupon drawer example does not send coupon codes to the emails entered. This is only an example to show how to customize your storefront theme.