How to build a Shopify theme app extension with React, Tailwind and Webpack

mittlus

Christian Mittler

Posted on October 22, 2023

How to build a Shopify theme app extension with React, Tailwind and Webpack

You can also read this post on Medium and Substack. An exemplary projects with all files mentioned in this article can be found on this Github Repository.

While I was in the process of building a Shopify App which integrates into the storefront, I learned that extensions are completely based on the Liquid templating language.

Since I already have experience with React development, I was looking for a simple way to integrate a React app into my extension. After looking around for a bit, I found some loose ideas and Github repositories using Vite (credits to https://github.com/iskurbanov/theme-app-extension-react).

But those repositories do not show the implementation process from scratch, which would be very helpful for people who are in the middle of development. Furthermore, I used the Remix template provided by Shopify for my project, which uses Webpack for bundling already. Since I couldn’t find instructions on how to inject a React project into Liquid via Webpack, I wrote this article to help other people achieve this more easily in the future. So without further detours, this is how I did it.

Contents

  1. Create a Shopify theme extension
  2. Create a new React app (or use an existing one)
  3. Install and configure Tailwind
  4. Install and configure Webpack
  5. Deploy!

Create a Shopify theme extension

Navigate into your project folder and run the following command:

npm run shopify app generate extension
npm run deploy
Enter fullscreen mode Exit fullscreen mode

Select Theme App Extension and provide a name for your extension. This creates an extensions folder along with a folder for your extension in it. In this folder, a couple of files with a simple extension example are generated as well. Open the Liquid file in the assets folder and replace the contents with the following code:

<span>This is Liquid</span>
<div id="container"></div>

{% schema %}
  {
    "name": "React Extension Tutorial",
    "target": "section",
    "javascript": "react-extension.js",
    "settings": []
  }
{% endschema %}
Enter fullscreen mode Exit fullscreen mode

The schema section will bind our bundled React project to the Liquid file, while ‘container’ div acts as its root element.

The detailed process to create a Shopify theme extension is described in the Shopify Developer Documentation.

Create a new React app (or use an existing one)

Navigate into your projects root folder and execute the following commands (replace my-app with your react extensions name).

npx create-react-app my-app
cd my-app
npm start
Enter fullscreen mode Exit fullscreen mode

Navigate into the src folder in your newly created React project, open the index.js file and replace its contents with the following code:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('container'));
root.render(
  <span className="text-blue-400">
    This is React!
  </span>
);
Enter fullscreen mode Exit fullscreen mode

This will specify the previously created ‘container’ div in the Liquid file as the root element of the React app.

The detailed process to create a React app is described in the React Documentation.

Install and configure Tailwind

Install the following packages:

npm tailwindcss postcss autoprefixer

Create a tailwind tailwind.config.js file with the following contents in the root of your React project:

module.exports = {
  content: ["./src/**/*.{js,jsx}", "./public/index.html"],
  theme: {
    extend: {
      colors: {
        primary: "#1B73E8",
      },
    },
  },
  plugins: [],
};
Enter fullscreen mode Exit fullscreen mode

Add Tailwind classes to index.css:

@tailwind base;
@tailwind components;
@tailwind utilities;
Enter fullscreen mode Exit fullscreen mode

Install and configure Webpack

Install the following packages packages:

npm install webpack webpack-cli @babel/cli @babel/core @babel/preset-env @babel/preset-react babel-loader css-loader postcss-loader style-loader terser-webpack-plugin

Create webpack.config.js with the following content in the root folder of your React project:

const TerserPlugin = require("terser-webpack-plugin");
const path = require("path");

module.exports = {
  mode: "production",
  entry: "./src/index.js",
  output: { path: path.resolve(__dirname, "../extensions/react-extension/assets"), filename: "react-extension.js" },
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: "babel-loader",
        exclude: /node_modules/,
      },
      {
        test: /\.css$/i,
        use: ["style-loader", "css-loader", "postcss-loader"],
      },
    ],
  },
  optimization: {
    minimizer: [
      new TerserPlugin({
        extractComments: false,
      }),
    ],
  },
};
Enter fullscreen mode Exit fullscreen mode

This configuration will bundle your whole React package into one Javascript file, which will be created in your extensions/react-extension/assets folder. Note that depending on your further development its possible that this configuration will not be sufficient anymore (e.g. because of specific file types, which require special loaders, etc.).

Create a .babelrc with the following content in the root folder of your React project:

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

Change build command command in your package.json to webpack:

"scripts": {
  "build": "webpack",
}
Enter fullscreen mode Exit fullscreen mode

Now you simply have to bundle your react project using the command we just added:

npm run build

Note that you have to run this everytime you commit changes to your React project! I’ve noticed that sometimes the hot reload doesn’t catch on to some changes after bundling the project. If this happens to you, either try to restart you Shopify app or deploy another version of it.

Deploy!

Lastly, to publish the changes made to your Shopify expansion, simply run the deployment command again:

npm run deploy

Thats it! You should now be able to add the theme app extension to your Shopify theme as an app block:

Add the theme app extension as a block
After adding the extensions app block, the two spans from the Liquid file and React project should now be displayed on the chosen page.

React app injected into the app extension, displayed on the product page
I hope this small tutorial helped you with implementing React into your Shopify theme app extension. If thats the case or you have any questions, feel free to comment or connect with me on social media:

Twitter

💖 💪 🙅 🚩
mittlus
Christian Mittler

Posted on October 22, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related