DEV Community

Cover image for How to build an ECommerce App with React
Ashutosh Kumar Singh for Stormkit

Posted on

How to build an ECommerce App with React

In this tutorial, we will build an E-commerce App with React using ButterCMS and Snipcart. We will use Chakra UI, a modular and accessible component library, to style the app.
Finally, we will deploy our ecommerce app with Stormkit, a serverless deployment service for JavaScript apps similar to Vercel or Netlify.

If you want to jump right into the code, check out the GitHub Repo here.

And here's a link to the deployed version: https://yakscythe-49dgnn.stormkit.dev/.

Prerequisites

What is ButterCMS

ButterCMS is a SaaS start-up that delivers value to Developers and Marketers through a headless, API-based CMS (Content Management System) and blogging platform. Butter is a developer-friendly CMS that enables developers to build modern apps while also providing their marketing teams with the tools needed to make website content updates.

What is Snipcart

Snipcart is HTML based fully customizable shopping cart that you can integrate with any web stack in few simple steps and start accepting international payments in minutes. With Snipcart's management dashboard, you can track abandoned carts, sales, orders, customers, and more.

Snipcart works perfectly with Headless CMS like Butter and speeds up your development process, provides better security, and functionality to your ecommerce app.

What is Stormkit

Stormkit is a serverless hosting and deployment service for JavaScript applications. It enables you to focus on developing your application instead of wasting time by automating deployments, logs, hosting, scaling, TLS certificates and much more with state of the art best practices and features like multiple environments, staged rollouts, remote Config and snippets. This makes Stormkit something like a low-code frontend infrastructure service for developers.

How to Setup and Install React

In this tutorial, you will use Create React App template to quickly create the initial React app. Run the following command in the terminal.

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

The last command, npm start, will start the React development server on your system's port 3000. Head over to http://localhost:3000/ in your browser to view your React app.

React App

You can stop the development server by hitting CTRL+C in the terminal.

In this tutorial, you will use Chakra UI to style your ecommerce app. Run the following command to install Chakra UI.

npm i @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^4 react-icons
Enter fullscreen mode Exit fullscreen mode

Update src/index.js to wrap your react app with the ChakraProvider component.

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { ChakraProvider } from "@chakra-ui/react";

ReactDOM.render(
  <React.StrictMode>
    <ChakraProvider>
      <App />
    </ChakraProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

reportWebVitals();
Enter fullscreen mode Exit fullscreen mode

Create a .env file to store ButterCMS and Snipcart API keys securely as environment variables. Run the following command to create the .env file.

touch .env
Enter fullscreen mode Exit fullscreen mode

The next step is to create a free ButterCMS account. After creating an account, head over to https://buttercms.com/settings/ and copy the Read API Token.

ButterCMS API Token

Navigate to https://app.snipcart.com/register in your browser and create a free Snipcart account if you haven't already.

Snipcart Account

After creating the Snipcart account, head over to account settings and copy the PUBLIC TEST API KEY under Credentials.

Snipcart API Key

Paste both Butter CMS API Key and Snipcart Public Test API Key in the .env file as shown below.

REACT_APP_BUTTER_ECOMMERCE=''
REACT_APP_SNIPCART_KEY=''
Enter fullscreen mode Exit fullscreen mode

How To Create Products on Butter

In this section, you will create the products for your ecommerce app on Butter. In this tutorial, you will create an ecommerce platform named Cookie Jar, where customers can buy different varieties of cookies. Hence, the products for this ecommerce platform will be cookies.

Navigate to your Butter Dashboard and then create a new collection named cookies with the following fields.

  • id - Type: Number - isRequired
  • name - Type: Short Text - isRequired
  • description - Type: Long Text - isRequired
  • price - Type: Number - isRequired
  • image - Type: Media - isRequired

You can create an ecommerce app on any product like shoes, sports stuff, craft, etc. You can add additional fields like ratings, reviews, stock, etc., to your ecommerce app, but these are the bare minimum required for any ecommerce app.

You can add the fields by dragging and dropping the corresponding field types.

Fields Drag N Drop

After adding the fields, click on the Create Collection button, name the collection cookies, and hit Save as a Collection.

New Cookie

You will also need to add some dummy data to the cookies collection. You can either copy the dummy data from https://yakscythe-49dgnn.stormkit.dev/ or add your favorite cookies.

Make sure to hit Publish after adding the cookies, aka products. You can come back and add more products or edit them whenever you want.

Publish

Here is how your cookies collection will look after adding products to it.

ButterCMS Cookies Collection

How To Fetch and Display Products

In this section, you will fetch the data from Butter CMS and display them as products on your ecommerce app.

You will use the buttercms library to fetch data from ButterCMS. Run the following command in your project's root directory to install buttercms.

npm i buttercms
Enter fullscreen mode Exit fullscreen mode

Update App.js file with the following code.

import { useState, useEffect } from "react";
import Butter from "buttercms";

const butter = Butter(process.env.REACT_APP_BUTTER_ECOMMERCE);

function App() {
  const [products, setProducts] = useState([]);

  useEffect(() => {
    async function fetchData() {
      const res = await butter.content.retrieve(["cookies"], {
        order: "name",
      });
      const { data } = await res.data;
      const allProducts = data.cookies;
      setProducts(allProducts);
    }
    fetchData();
  }, []);
  return (
    <div>
      {products.map((product) => (
        <div>
          <img src={product.image} alt={`${product.name}`} />
          {product.name}
          {product.price}
          {product.description}
        </div>
      ))}
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

In the above code, you start by creating an instance of Butter using your ButterCMS API key stored in .env file and accessed using process.env.REACT_APP_BUTTER_ECOMMERCE.

Then you create a state named products to store the data fetched from ButterCMS using the useState() hook. Hooks are functions that use React features like defining a state without writing a class.

You fetch the collection named cookies using butter's .retrieve() method inside the React's useEffect() hook.

You then access the response from ButterCMS and store it inside the products state using the setProducts() method. Here is how the state products look like.

[
  {
    "meta": {
      "id": 125151
    },
    "id": "1",
    "name": "Biscotti Cookies",
    "price": 40,
    "description": "Biscotti actually means “twice baked” and the cookie is indeed baked twice, resulting in its hard and crunchy texture.",
    "image": "https://cdn.buttercms.com/UqbFGAJLTGqtYqF2UajV"
  },
  {
    "meta": {
      "id": 113778
    },
    "id": "2",
    "name": "Chocolate Chip Cookies",
    "price": 30,
    "description": "Chocolate chip cookies are the perennial classic and longtime fan favorite. ",
    "image": "https://cdn.buttercms.com/Xe1zfNvRCiOOI4LPuoVb"
  }
]
Enter fullscreen mode Exit fullscreen mode

To display the product's data, you iterate over the products state using the .map() method and display the data on the page using curly brackets {}.

{
  products.map((product) => (
    <div>
      <img src={product.image} alt={`${product.name}`} />
      {product.name}
      {product.price}
      {product.description}
    </div>
  ))
}
Enter fullscreen mode Exit fullscreen mode

Head over to http://localhost:3000/. Here is how your ecommerce app will look like.

App without Styling

Though your app needs styling, but you are getting all the required data from ButterCMS successfully. Now, you will use Chakra UI to style the app. Update App.js with Chakra UI components to style your ecommerce app.

import {
  Container,
  Text,
  Divider,
  Box,
  Image,
  Button,
  SimpleGrid,
  Flex,
} from "@chakra-ui/react";
import { FiShoppingCart, FiShoppingBag } from "react-icons/fi";
import { useState, useEffect } from "react";
import Butter from "buttercms";

const butter = Butter(process.env.REACT_APP_BUTTER_ECOMMERCE);

function App() {
  const [products, setProducts] = useState([]);

  useEffect(() => {
    async function fetchData() {
      const res = await butter.content.retrieve(["cookies"], {
        order: "name",
      });
      const { data } = await res.data;
      const allProducts = data.cookies;
      setProducts(allProducts);
    }
    fetchData();
  }, []);

  return (
    <Container maxW="container.xl" h="100vh" >
      <Flex justifyContent="space-between" alignContent="center">
        <Text
          as="a"
          href="/"
          fontSize="2rem"
          color="gray.900"
          fontFamily="Robo"
          my="5px"
        >
          Cookie Jar
        </Text>
        <Button
          my="5px"
          colorScheme="green"
          variant="ghost"
          leftIcon={<FiShoppingBag size="24px" />}
          size="lg"
          p={2}
        >
          View Cart
        </Button>
      </Flex>
      <Divider />
      <Box mt={4}>
        <SimpleGrid
          minChildWidth="300px"
          align="center"
          justify="center"
          spacing="40px"
          mb={32}
        >
          {products.map((product) => (
            <Box
              bg="white"
              maxW="sm"
              borderWidth="1px"
              rounded="lg"
              shadow="lg"
              _hover={{ shadow: "dark-lg" }}
              key={product.id}
            >
              <Image
                h="350px"
                fit="cover"
                src={product.image}
                alt={`Picture of ${product.name}`}
                roundedTop="lg"
              />

              <Box p="6">
                <Flex
                  mt="1"
                  justifyContent="space-between"
                  alignContent="center"
                >
                  <Text
                    fontSize="2xl"
                    fontWeight="semibold"
                    as="h4"
                    textTransform="uppercase"
                    lineHeight="tight"
                    fontFamily="Roboto"
                  >
                    {product.name}
                  </Text>
                  <Text
                    as="h4"
                    fontSize="2xl"
                    fontWeight="bold"
                    color="teal.600"
                  >
                    ${product.price}
                  </Text>
                </Flex>

                <Text
                  mt={2}
                  color="gray.500"
                  display={{ base: "none", md: "flex" }}
                >
                  {product.description}
                </Text>

                <Button
                  leftIcon={<FiShoppingCart size="24px" />}
                  size="lg"
                  mt={4}
                  isFullWidth
                  colorScheme="blue"
                  variant="outline"
                  alignSelf={"center"}

                >
                  Add to Cart
                </Button>
              </Box>
            </Box>
          ))}
        </SimpleGrid>
      </Box>
    </Container>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

In the above code, you import different Chakra UI components like Container, Flex, etc., and use them to style your app. Except for styling, the code used to fetch and display the data on the app remains the same.

In this tutorial, we will not discuss how these components are used in-depth; you can refer to official Chakra UI docs to learn more about these components.

Here is how your app will look.

Chakra UI Styled App

You have created two buttons in the above code, View Cart, which shows users their cart, and Add to Cart, which adds the product to the cart. These buttons don't work yet; you will integrate them with Snipcart in the next section.

How To Integrate Snipcart With React App

In this section, you will configure and integrate Snipcart with your ecommerce app.

Update public/index.html file and add the following code inside the <Head> tag.

<link rel="preconnect" href="https://app.snipcart.com">
<link rel="preconnect" href="https://cdn.snipcart.com">
<link rel="stylesheet" href="https://cdn.snipcart.com/themes/v3.2.0/default/snipcart.css"/>
Enter fullscreen mode Exit fullscreen mode

Now, add the following code in public/index.html before closing <Body> tag.

<script
  async
  src="https://cdn.snipcart.com/themes/v3.2.0/default/snipcart.js"
></script>
<div
  id="snipcart"
  data-config-modal-style="side"
  data-api-key="%REACT_APP_SNIPCART_KEY%"
  hidden
></div>
Enter fullscreen mode Exit fullscreen mode

The Snipcart API Key stored in .env file is being accessed in the above code using %REACT_APP_SNIPCART_KEY%.

Update Add to Cart button in src/App.js like this.

<Button
  leftIcon={<FiShoppingCart size="24px" />}
  size="lg"
  mt={4}
  isFullWidth
  colorScheme="blue"
  variant="outline"
  alignSelf={"center"}
  className="snipcart-add-item"
  data-item-id={product.id}
  data-item-image={product.image}
  data-item-name={product.name}
  data-item-url="/"
  data-item-description={product.description}
  data-item-price={product.price}
>
  Add to Cart
</Button>
Enter fullscreen mode Exit fullscreen mode

In the above code, you pass the data required by Snipcart, like the product's name, id, description, etc.

Here is the Add to Cart button in action.

Add to Cart GIF

Finally, update the View Cart button like with className="snipcart-checkout".

<Button
  my="5px"
  colorScheme="green"
  variant="ghost"
  leftIcon={<FiShoppingBag size="24px" />}
  size="lg"
  p={2}
  className="snipcart-checkout"
>
  View Cart
</Button>
Enter fullscreen mode Exit fullscreen mode

This button will show the current items in the cart to the user.

View Cart GIF

Run the following commands in the terminal to commit your code.

git add .
git commit -m"Finished building the React Ecommerce app"
Enter fullscreen mode Exit fullscreen mode

How to Deploy your Ecommerce App with Stormkit

In this section, you will deploy the ecommerce app with the free tier of Stormkit.

The first step is to push your code to a GitHub repository. Create an account on https://github.com/ if you haven't already.

Create an account on GitHub

Navigate to https://github.com/new and create a new GitHub repo with react-ecommerce-butter as the repo name. You can skip other fields for now. Finally, click on the Create repository button.

Create new Repo

On the next page, you will be provided with the code to push your code to GitHub. Copy the commands from the second section, i.e., ...or push an existing repository from the command line section.

Push Commands

The commands will be similar to this but will contain your GitHub username.

git remote add origin https://github.com/lelouchB/react-ecommerce-butter.git
git branch -M main
git push -u origin main
Enter fullscreen mode Exit fullscreen mode

The last command will push your code to GitHub. Head over to https://app.stormkit.io/auth and login using GitHub OAuth.

Stormkit account

Click on the GitHub icon under Where can we find your codebase?

Where can we find your codebase?

You will be asked to connect your repositories with Stormkit. You can choose to connect all your repositories or select only the react-ecommerce-butter repo.

Select the react-ecommerce-butter repository and proceed further.

Select the repo

You will be redirected to your Stormkit dashboard, where your newly connected app would appear. Select the app you want to deploy.

Stormkit Dashboard with New App

On your app dashboard, you will be provided with a default production environment. You can create as many environments as you want. In this tutorial, we will deploy using the default production environment.

Before deploying, you will need to set the environment variables in your production environment; else your deployment will fail.

Click on the production environment.

Production Enviroment

Now, click on the Edit button or the pencil icon to edit the environment configurations.

Edit Configurations

A modal will appear with current environment configurations.

Modal with Enviroment Configurations

Scroll to the bottom of the modal; you will see the Build configuration and Environment variables sections.

Under Build configuration, type build under Public folder field and add npm run build command under Build command field.

Build configuration

Under Environment variables, add REACT_APP_BUTTER_ECOMMERCE and REACT_APP_SNIPCART_KEY environment variables with their values and click on the Update environment button.

Environment Variables

Finally, click on the Deploy now button to deploy your app.

Deploy Now

A modal will appear to select the environment, select the production environment and click on Deploy now.

Choose Enviroment and Deploy

The Deploy now will trigger the deployment process, which you can see live on your dashboard.

Deployment Process

After the deployment process completes, you will be provided with a preview URL of your deployed website.

If the preview looks good, you can publish it to production by going to the Deployments tab and clicking on the triple dots across the latest commit, i.e., Finished building the React Ecommerce app.

Publish button

A modal will appear, deselect the sync sliders option and then scroll the bar to 100%, i.e., to the end. Finally, click on Publish to production button to publish the app.

Publish to production

Congratulations, your ecommerce app has been deployed. You can see the deployed version of this project here.

Congrats

Conclusion

In this tutorial, we learned how to build an Ecommerce App with React.js using ButterCMS and Snipcart. Finally, we deployed our ecommerce app with Stormkit. You can follow this tutorial and create your own version of this project.

Here are a few ideas to get you started:

Here are some additional resources that can be helpful:

Happy coding!

Top comments (3)

Collapse
 
abhishek_san profile image
Abhishek Prasad

great work....can you help me I got stuck in my project. visit the link I have posted it on stack overflow
stackoverflow.com/q/68237209/16271816

Collapse
 
kwing25 profile image
Kendra Wing

Great Tutorial. I've had a hard time finding good React Ecommerce Tutorials and this one really helped me. Thanks!

Collapse
 
fahimuddin98 profile image
FAHIMUDDIN

Thanks for this this amazing project