Introduction to Next.js E-commerce: Snipcart Integration
- Md. Saad
- May 06, 2024
In today's digital age, establishing an online presence for your business is essential to reach a broader customer base and increase revenue. If you've built your website using Next.js, known for its speed and simplicity, you may wonder how to seamlessly incorporate eCommerce functionality. Fortunately, Next.js flexibility allows for integrating various eCommerce solutions, and one such powerful option is Snipcart. In this guide, I will walk you through adding eCommerce functionality to your Next.js website using Snipcart.
What is Snipcart?
Snipcart is a JavaScript-based shopping cart platform that can be effortlessly integrated into Next.js websites, transforming your site into a fully functional eCommerce platform. Snipcart offers a user-friendly and customizable solution that requires minimal development effort, whether you're selling physical products, digital downloads, or services.
Prerequisites
- You’ll need a Snipcart account to sign up for free Snipcart.
- Ensure you have an existing web project built with Next.js.
What are we going to do?
We will create a very Next.js website that will show the products. We also create a data folder to add all the product details. Then, we will integrate the Sinpcart in it.
Your Next.js Project
I hope you have already created your next.js project. If not, create one using:
npx create-next-app <app-name>
This will create a simple next js project and this should have the following file structure.
For more detailed info, read the article. Now, go to the folder and run the project.
cd <app-name>
npm run dev
The site will be open on the port localhost:3000. Now it is time to configure the site.
Customize Site Layout
Now our site will show a blank home page. Let’s create a basic layout for the site. We will add a Navbar and a Footer so that it can be shown for all the pages on the site.
To add Navbar create a components folder and inside it, create a file named Navbar.jsx.
Now add the following codes to add a simple navbar.
import React from "react";
import logo from "../public/vercel.svg";
import Image from "next/image";
import Link from "next/link";
const Navbar = () => {
return (
<header className="py-2.5 bg-white">
<div className="container mx-auto">
<nav className="flex items-center">
<div className="logo">
<Link href="/">
<Image
src={logo}
alt="logo"
width={50}
height={30}
/>
</Link>
</div>
<ul className="ml-auto flex items-center">
<li>
<a
href="#"
className="text-black flex items-start"
>
<svg
width="31"
height="27"
viewBox="0 0 31 27"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M1.10512 0.368718C0.560256 0.368718 0.118164 0.812066 0.118164 1.35848C0.118164 1.9049 0.560256 2.34824 1.10512 2.34824H4.90887L8.30138 18.4009C8.43503 19.0053 8.83085 19.5079 9.32946 19.5041H25.7788C26.3005 19.5118 26.7799 19.0375 26.7799 18.5143C26.7799 17.9911 26.3006 17.5168 25.7788 17.5245H10.1315L9.71003 15.545H27.095C27.5371 15.5412 27.9547 15.2048 28.0511 14.7718L30.354 4.87412C30.4825 4.29933 29.9852 3.67172 29.3979 3.66786H7.21171L6.6771 1.15221C6.58329 0.71276 6.15921 0.368652 5.7107 0.368652L1.10512 0.368718ZM7.623 5.64746H12.7634L13.2569 8.61674H8.25005L7.623 5.64746ZM14.7785 5.64746H20.9881L20.4946 8.61674H15.2719L14.7785 5.64746ZM23.0031 5.64746H28.1537L27.4649 8.61674H22.5097L23.0031 5.64746ZM8.67181 10.5963H13.5862L14.0797 13.5656H9.29919L8.67181 10.5963ZM15.6009 10.5963H20.1656L19.6721 13.5656H16.0944L15.6009 10.5963ZM22.1807 10.5963H27.0023L26.3135 13.5656H21.6872L22.1807 10.5963ZM12.6197 20.164C10.8141 20.164 9.32979 21.6525 9.32979 23.4632C9.32979 25.2739 10.8141 26.7624 12.6197 26.7624C14.4252 26.7624 15.9095 25.2739 15.9095 23.4632C15.9095 21.6525 14.4252 20.164 12.6197 20.164ZM22.4892 20.164C20.6837 20.164 19.1994 21.6525 19.1994 23.4632C19.1994 25.2739 20.6837 26.7624 22.4892 26.7624C24.2948 26.7624 25.7791 25.2739 25.7791 23.4632C25.7791 21.6525 24.2948 20.164 22.4892 20.164ZM12.6197 22.1435C13.3586 22.1435 13.9356 22.7222 13.9356 23.4632C13.9356 24.2042 13.3586 24.7829 12.6197 24.7829C11.8807 24.7829 11.3037 24.2042 11.3037 23.4632C11.3037 22.7222 11.8807 22.1435 12.6197 22.1435ZM22.4892 22.1435C23.2282 22.1435 23.8052 22.7222 23.8052 23.4632C23.8052 24.2042 23.2282 24.7829 22.4892 24.7829C21.7503 24.7829 21.1733 24.2042 21.1733 23.4632C21.1733 22.7222 21.7503 22.1435 22.4892 22.1435Z"
fill="#9094FF"
></path>
</svg>
<span className="-mt-2 flex justify-center items-center bg-fuchsia-500 w-6 h-6 rounded-full text-sm snipcart-items-count text-white font-bold"></span>
</a>
</li>
</ul>
</nav>
</div>
</header>
);
};
export default Navbar;
This will create a nice simple Navbar. I have used Tailwind for styling. You can use your custom CSS files too.
Now, add a Footer for the site. To add Navbar create a components folder and inside it, create a file named Footer.jsx and add the following codes.
import React from "react";
const Footer = () => {
return (
<div className="mt-24">
<div className="container mx-auto">
<p className=" text-center">{new Date().getFullYear()} Test. All Rights Reserved</p>
</div>
</div>
);
};
export default Footer;
This will create a nice simple Footer. Finally, add these two files to the app/layout.js file. Your layout will look like this:
import {Inter} from "next/font/google";
import "./globals.css";
import Navbar from "@/components/Navbar";
import Footer from "@/components/Footer";
import Script from "next/script";
const inter = Inter({subsets: ["latin"]});
export const metadata = {
title: "Test",
description: "Generated by create next app",
};
export default function RootLayout({children}) {
return (
<html lang="en">
<body className={inter.className}>
<Navbar />
<main>{children}</main>
<Footer />
</body>
</html>
);
}
Showing Products
As we have successfully configured the layout and created a blank home page, now it is time to add products and add them to the home page. This part will be divided in three steps:
- Create Product Data
- Add Product component
- Add Product components on the home page
Let’s go through these steps.
Create product data:
Add a new folder named data. Inside it, create a file named products.js. Now add data of the products in it. Sample data is given below:
export const ProductList = [
{
id: "halfmoon",
name: "Halfmoon Betta",
price: 25.0,
image: "/halfmoon.jpg",
description:
"The Halfmoon betta is arguably one of the prettiest betta species. It is recognized by its large tail that can flare up to 180 degrees.",
},
{
id: "dragonscale",
name: "Dragon Scale Betta",
price: 35,
image: "/dragonscale.jpg",
description:
"The dragon scale betta is a rarer and higher maintenance fish. It is named by its thick white scales covering his sides that looks like dragon scale armor.",
},
{
id: "crowntail",
name: "Crowntail Betta",
price: 7.5,
image: "/crowntail.jpeg",
description:
"The crowntail is pretty common, but interesting none the less. It's recognized by the shape of its tail that has an appearance of a comb.",
},
{
id: "veiltail",
name: "Veiltail Betta",
price: 5.0,
image: "/veiltail.jpg",
description: "By far the most common betta fish. You can recognize it by its long tail aiming downwards.",
},
];
Feel free to add more data.
Add Product component
We need to add a product component to make a product layout. This layout will get props. All the product values will be passed through this prop. Let’s first, create a Products.jsx file in the components folder. Now, add the following code:
import Image from "next/image";
import Link from "next/link";
import React from "react";
const Products = ({products}) => {
return (
<article>
<Link href={`/product/${products.id}`}>
<h2> {products.name}</h2>
</Link>
<p>{products.description}</p>
<p>{products.price}</p>
<Image
src={products.image}
alt="ds"
width={350}
height={350}
className="h-auto w-auto"
/>
<button
className={`snipcart-add-item`}
>
Add to cart
</button>
</article>
);
};
export default Products;
Here all the product pieces of information are passing through products prop. Later on the homepage, we will assign the product data in this prop.
Add Product components on the home page
So far, we have created product data files and product components for the home page where all the products will be shown. Let's discuss on it
At first, We will remove all the pre-added data from the home page. Go to the app/page.jsx page and remove all the data. At this moment our app/page.jsx codes will look like this:
export default function Home() {
return (
);
}
Now import Product components and product Data on the page.
import Products from "@/components/Products";
import {ProductList} from "@/data/products";
Now add the following code in the Home function:
<>
<div className="container mx-auto">
<div className="grid grid-cols-3 gap-5">
{ProductList &&
ProductList.map((productList, index) => (
<Products
products={productList}
key={index}
/>
))}
</div>
</div>
</>
This code will iterate each product and assign product value for the prop products. Finally show all the products on the home page. Your final codes on app/page.jsx should look like these:
import Products from "@/components/Products";
import {ProductList} from "@/data/products";
export default function Home() {
return (
<>
<div className="container mx-auto">
<div className="grid grid-cols-3 gap-5">
{ProductList &&
ProductList.map((productList, index) => (
<Products
products={productList}
key={index}
/>
))}
</div>
</div>
</>
);
}
Adding Snipcart To the site
So far, we have created a product page. Now, it is time to add Snipcart functionality to it. Let’s Follow the steps to do that:
- Go to app/layout.js file and paste the following codes under Footer Components.
<Script src="https://cdn.snipcart.com/themes/v3.2.1/default/snipcart.js" />
<div
hidden
id="snipcart"
data-api-key="Your Public API Key From Snipcart Account "
>
</div>
Add your Public API Keyfrom Snipcart account in the data-api-key. You may also need to import the script from next/script; To do it add the code on top:
import Script from "next/script";
- Now create a preload-resources.js file in the app folder and use the following codes to add some pre-connect codes on the head element:
"use client";
import ReactDOM from "react-dom";
export function PreloadResources() {
ReactDOM.preconnect("https://app.snipcart.com");
ReactDOM.preconnect("https://cdn.snipcart.com");
return null;
}
- Now import it into the app/layout.js. Then we have to add Snipcart default CSS to show the Snipcart eCommerce pages. So, create a CSS file in the app folder and import it to the app/layout.js file. I have named it snipcart.css. You can name it whatever you like. Copy the CSS codes from the link and paste them into the CSS file you created.
- Finally, as we have reconfigured the app/layout.js file, Now this file will look like this:
import {Inter} from "next/font/google";
import "./globals.css";
import "./snipcart.css";
import {PreloadResources} from "./preload-resources";
import Navbar from "@/components/Navbar";
import Footer from "@/components/Footer";
import Script from "next/script";
const inter = Inter({subsets: ["latin"]});
export const metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({children}) {
return (
<html lang="en">
<PreloadResources />
<body className={inter.className}>
<Navbar />
<main>{children}</main>
<Footer />
<Script src="https://cdn.snipcart.com/themes/v3.2.1/default/snipcart.js" />
<div
hidden
id="snipcart"
data-api-key="OTY2N2FkM2UtZTQ4My00NzUxLTg2ODEtYzFmNTliYWNmZWY5NjM4MzAwMjk4ODY3MDc1NTk4"
></div>
</body>
</html>
);
}
Reconfigure the Product Components
We have almost completed the setup. To finish the setup, We have to re-configure the components/Products.jsx a little bit. At this moment, Our button in the product components does not do anything. Let’s add Snipcart values to make it functionalize. So, add the following code on the button:
data-item-id={products.id}
data-item-name={products.name}
data-item-price={products.price}
data-item-url={`/product/${products.id}`}
data-item-image={products.image}
You can add more items. But for this article, we will use these only. Read the Snipcart documentation to add more items. THus, your final codes on the components/Products.jsx will be these:
import Image from "next/image";
import Link from "next/link";
import React from "react";
const Products = ({products}) => {
return (
<article>
<Link href={`/product/${products.id}`}>
<h2> {products.name}</h2>
</Link>
<p>{products.description}</p>
<p>{products.price}</p>
<Image
src={products.image}
alt="ds"
width={350}
height={350}
className="h-auto w-auto"
/>
<button
className={`snipcart-add-item`}
data-item-id={products.id}
data-item-name={products.name}
data-item-price={products.price}
data-item-url={`/product/${products.id}`}
data-item-image={products.image}
>
Add to cart
</button>
</article>
);
};
export default Products;
Congratulations! We've successfully added eCommerce functionality to our Next.js website using Snipcart.
Create a Product single page as Bonus
Our site should function nicely, Yet, we do not have any product details page. Let’s create one.
- Create an app/product folder.
- Inside it create another folder but this time close it with []. I have used product id to link it so the folder name is [id].
- Now, Add a page.jsx file in the [id] folder.
- Finally, add the following codes to show Product information.
import React from "react";
import {ProductList} from "@/data/products";
import Image from "next/image";
const ProductSingle = (props) => {
const productId = props.params.id;
const data = ProductList.find((post) => post.id === productId);
return (
<div className="container mx-auto">
<article className="mx-auto max-w-[800px] grid grid-cols-2 gap-10 mt-32">
<div className="relative">
<Image
src={data.image}
alt="ds"
className="h-auto w-auto"
fill={true}
/>
</div>
<div>
<h1 className="mb-5">{data.name}</h1>
<p className="mb-5">{data.price}</p>
<p className="mb-5">{data.description}</p>
<button
className={`snipcart-add-item`}
data-item-id={data.id}
data-item-name={data.name}
data-item-price={data.price}
data-item-url={`/product/${data.id}`}
data-item-image={data.image}
>
Add to cart
</button>
</div>
</article>
</div>
);
};
export default ProductSingle;
Styling Your Site
I have used Tailwind to style buttons and other items. However, you can use any CSS framework you want.
I have also used the default cart template of Snipcart, which is the full-page cart. However, you can use the other one, which is a side modal. The default style is the full-page cart. For more details, you can read here.
Testing Your Site Locally
Run your site locally using npm run dev and test the eCommerce functionality by adding products to the cart and going through the checkout process. If you face any errors in the checkout process, please read the full documentation from Store Set Up to set up your store correctly.
That's all. We have successfully created a simple eCommerce site using Next.js and Snipcart. To create a customizable eCommerce site, feel free to contact us.
Create a Next.js app from Scratch (Beginner Guide)
A step-by-step guide to creating a next.js app from scratch for beginners.
Read article