719-286-0751 [email protected]

React + Tailwind on a Shopify Theme

If you are like me, coming from React into the world of Shopify, I’m sure you’ve wanted to implement a React package like Toastify into your theme. Unfortunately, is not as simple as if you were on a NextJS or CRA app but it’s definitely possible.

In this tutorial we will be creating React components using our own Babel + Webpack configuration. As a bonus, we will also be adding Tailwind. There’s a lot of steps involved so let’s get started.

Requirements

Node.js

Yarn (Recommended, but you can also use NPM)

0. Themekit

We will assume you’ve already configured Themekit to properly deploy your files to Shopify. If you need the steps please follow the official guide and come back here

1. Install Compilers

Let’s start by creating a new package.json which will hold all of our dependencies:

npm init -y

Once you have that ready, add Babel & Webpack using the following script

yarn add --dev @babel/cli @babel/core @babel/preset-env @babel/preset-react babel-loader css-loader mini-css-extract-plugin webpack webpack-cli

2. Configuration

We need to create two configuration files:

.babelrc

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

webpack.config.js

const path = require("path");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
    mode: "production",
    entry: {
        // Components belong here
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: ["babel-loader"],
            },
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    "css-loader",
                ],
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            // Source file
            filename: "style.css",
            // Destination file, feel free to change the name
            chunkFilename: "style.css",
        }),
    ],
    output: {
        filename: "[name].bundle.js",
        path: path.resolve(__dirname, "assets"),
    }
};

Lastly, let’s add two scripts to our package.json to make development easier

{
  "scripts": {
    "build": "webpack --progress --color",
    "watch": "webpack --progress --color --watch"
  }
}

Now, if you run yarn build it will compile everything once, if you run yarn watch it will compile every time you update a component.

3. Add React Component

Now time for the fun part, add React & ReactDom

yarn add react react-dom

I usually create a folder on the root theme called dev and put all my files in there. Create the folder, an empty stylesheet (more on this later) and a new JS file.

dev/style.css

/* This file is empty for now */

dev/like-button.js

class LikeButton extends React.Component {
    constructor(props) {
        super(props);
        this.state = {liked: false};
    }

    render() {
        if (this.state.liked) {
            return 'You liked this.';
        }

        return (
            
        );
    }
}

let domContainer = document.querySelector('#like_button_container');
ReactDOM.render(<LikeButton/>, domContainer);

Once that’s ready, let’s add our new component to the webpack config. I like naming my components starting with react- because this prevents me from overriding a theme file by mistake, plus it’s easier to identify. Let’s also add our empty stylesheet.

webpack.config.js

{
  "entry": {
    "style": "./dev/style.css", // Our empty stylesheet
    "react-like-button": "./dev/like-button.js" // One line per component
  }
}

Now our component is ready to be used on Shopify.
Create a new snippet, this will hold our React Component

snippets/react-like-button.liquid

<div id="like_button_container">div>
{{ 'react-like-button.bundle.js' | asset_url |  script_tag }}

Compile using yarn build and that’s it! You can now use {% include 'react-like-button' %} anywhere in your theme. For testing purposes you may add it on your layout/theme.liquid file

4. Third party React Components

Now that you’re using React you may also implement external packages. Let’s add Toastify

yarn add react-toastify

dev/like-button.js

import React from "react";
import ReactDOM from "react-dom"
import { ToastContainer, toast } from 'react-toastify';

class LikeButton extends React.Component {
    render() {
        return (
            <>
                <button onClick={() => toast('🦄 You liked this!')}>
                    Like
                button>
                <ToastContainer />
            
        );
    }
}

let domContainer = document.querySelector('#like_button_container');
ReactDOM.render(<LikeButton/>, domContainer);

I know what you are thinking, ‘where’s the style?’. This is where our MiniCssExtractPlugin comes in handy. Import the component’s style into our empty stylesheet.

dev/style.css

@import 'react-toastify/dist/ReactToastify.css';

Now, update the component liquid, and you’re all set!

snippets/react-like-button.liquid

<div id="like_button_container"></div>
{{ 'react-like-button.bundle.js' | asset_url | script_tag }}
{{ 'style.css' | asset_url | stylesheet_tag }}

5. Tailwind Support

As I’m sure you’ve heard, Tailwind is a great tool for creating gorgeous UIs with little to no css so let’s include it into our app.

We will be needing a few extra dependencies

yarn add --dev tailwindcss postcss-loader autoprefixer

5.1 Create Tailwind config file

tailwind.config.js

module.exports = {
  purge: {
    enabled: true, // Auto Purge
    content: ['./dev/*.js'] // Purge our components
  },
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {},
  },
  variants: {
    extend: {},
  },
  plugins: [],
};

 

5.1.1 Tailwind on Liquid files [Optional]

If you want to use Tailwind classes on your liquid files make sure you add them to the purgeable array


5.2 Create Postcss config file

postcss.config.js

module.exports = {
    plugins: [
        require('tailwindcss'),
        require('autoprefixer'),
    ],
};

5.3 Add Postcss to Webpack config

{
    test: /\.css$/,
    use: [
        MiniCssExtractPlugin.loader,
        "css-loader",
        "postcss-loader" <--- Add This line
    ]
}

5.4 Import tailwind from style.css

dev/style.css

@import 'react-toastify/dist/ReactToastify.css';

@tailwind base;
@tailwind components;
@tailwind utilities;

5.5 Done!

You may now use all tailwind classes and don’t worry, we’ve enabled purge so classes you are not using will be removed automatically.

Update your component just to make sure everything works. snippets/react-like-button.liquid

import React from "react";
import ReactDOM from "react-dom"
import { ToastContainer, toast } from 'react-toastify';

class LikeButton extends React.Component {
    render() {
        return (
            <>
                <button className="px-12 py-4 bg-blue-900 hover:bg-blue-600 text-white" onClick={() => toast('🦄 You liked this!')}>
                    Like
                button>
                <ToastContainer />
            
        );
    }
}

let domContainer = document.querySelector('#like_button_container');
ReactDOM.render(<LikeButton/>, domContainer);

5.6 Done!

We’ve created a repo which holds all the configuration explained here. Take a look!

Submit a Comment

Your email address will not be published. Required fields are marked *

Install our webapp on your iPhone! Tap and then Add to homescreen.
Share This