In today's fast-paced digital market, the success of an eCommerce store depends heavily on its speed, user experience, and search engine optimization (SEO). Customers demand fast-loading pages, smooth navigation, and Responsive Design that work seamlessly on any device. For online stores, these factors aren’t just nice-to-haves—they’re crucial for attracting, engaging, and converting visitors. This is where Next.js, a powerful React framework, proves invaluable for creating high-performance eCommerce stores. It combines the best of server-side rendering (SSR) and static site generation (SSG) to ensure fast load times, smooth user experiences, and excellent SEO.
At Prateeksha Web Design, we understand the unique needs of small businesses. We offer comprehensive Shopify Web Design services, including digital marketing, SEO, and social media marketing, all at competitive rates. Our mission is to help businesses build an online presence that maximizes visibility and fosters growth. Through this guide, we’ll walk you through building a high-performance eCommerce store using Next.js, highlighting the benefits of Next.js’s technology and best practices for performance optimization.
Certainly! Let’s expand on why Next.js is a powerful choice for eCommerce, providing more depth and real-world case studies to illustrate its benefits.
Next.js has become a go-to framework for building eCommerce sites because it brings together cutting-edge web technology with practical, performance-boosting features. It’s designed to handle everything from high-traffic loads to real-time dynamic content, making it ideal for eCommerce applications.
a. Server-Side Rendering (SSR): Next.js's server-side rendering (SSR) feature allows for pages to be pre-rendered on the server and then sent to the client. This not only speeds up the delivery of pages but also optimizes the browsing experience, especially for mobile users who may be on slower connections. SSR is especially useful for pages that require frequent updates, such as new product arrivals or flash sales, as it reduces load times by delivering fully-rendered content on the first request.
b. Static Site Generation (SSG): With SSG, pages are generated at build time rather than on-demand. This is ideal for sections that don’t change frequently, like homepage banners or static informational pages. By using both SSR and SSG, developers can configure parts of the store to be highly performant, balancing speed and server efficiency.
c. Image Optimization: Next.js has built-in support for optimized images, with features like automatic resizing and serving images in modern formats such as WebP. This improves load times significantly, especially for image-heavy eCommerce sites where product visuals play a central role in customer decisions.
a. Improved Indexability: Search engines rely heavily on text content and metadata when crawling a website. With SSR, content is fully rendered by the time it reaches the user’s browser, allowing search engines to crawl and index pages more efficiently. This is essential for eCommerce sites, where search engine visibility directly impacts traffic and conversion rates.
b. Enhanced Metadata Handling: Next.js supports a next/head
component that makes it easy to manage metadata, titles, descriptions, and canonical URLs dynamically. This flexibility is crucial for eCommerce sites with large catalogs and unique SEO requirements for each product page.
c. Structured Data Support: Schema markup can be easily integrated into Next.js to improve the presentation of products in search results, including prices, ratings, and availability. This structured data support increases click-through rates and improves search engine visibility for eCommerce stores.
a. Dynamic Routing: Next.js offers dynamic routing, which makes it easy to add new pages and manage URL structures as your catalog expands. For large eCommerce stores with thousands of products and multiple categories, this capability is critical for staying organized and efficient.
b. Serverless Functions and API Routes: Next.js can integrate serverless functions that handle backend processes, such as managing inventory and tracking user interactions, without the need for complex server setups. This enables real-time scaling based on the number of users or interactions, ensuring a smooth experience even during peak traffic.
c. Code Splitting and Lazy Loading: Next.js supports code-splitting by default, which allows for loading only the JavaScript required for the initial screen. This reduces the time to interactive (TTI) metric, enhancing the browsing experience. Lazy loading further boosts performance by only loading components as they’re needed, reducing initial load times and improving speed as users navigate the site.
a. Headless CMS Integration: Next.js works seamlessly with popular headless CMSs like Sanity, Contentful, and Shopify’s headless mode, enabling brands to manage content efficiently while maintaining a customizable, high-performance front end. This flexibility allows businesses to implement features like personalized product recommendations, complex filtering, and custom layouts.
b. API Flexibility: Next.js’s flexible API routes allow eCommerce businesses to connect to various third-party services, such as payment gateways, inventory management systems, and customer relationship management (CRM) software. This enables smooth order processing and enhances the overall store functionality.
c. Design Flexibility: Next.js’s component-based structure makes it easy for developers to build modular, reusable UI components that can be customized or reused across different parts of the store. Tailwind CSS, when paired with Next.js, simplifies creating responsive, mobile-first designs without compromising load speed.
a. HTTPS Compatibility: With Next.js, configuring HTTPS is straightforward, ensuring all data transferred between the server and client is encrypted. This is essential for eCommerce websites, which deal with sensitive information, including customer data and payment information.
b. API Security: Next.js allows developers to manage API calls securely, either through serverless functions or dedicated API routes. This reduces vulnerabilities and allows for data encryption at each interaction point, creating a safer shopping experience.
c. Third-Party Security Integrations: Next.js supports a wide range of third-party security tools, including Cloudflare, Snyk, and AWS Shield, making it possible to implement measures like DDoS protection, SSL/TLS certificates, and vulnerability scans.
a. Simplified Deployment with Vercel: Next.js was created by Vercel, and they’ve made deploying Next.js projects on their platform incredibly easy. Vercel’s global edge network allows for optimized content delivery, further enhancing site performance.
b. Real-Time Collaboration: Developers can collaborate in real-time using Vercel, which allows for quick previews and instant feedback. This is especially useful for eCommerce teams, where designers, developers, and marketers may need to work together to ensure the store’s layout and functionality meet business objectives.
c. TypeScript Support: Next.js has first-class support for TypeScript, a statically typed language that helps developers catch errors early and improve code quality. This support makes it easier to build robust, scalable applications that reduce the likelihood of bugs.
Next.js is an outstanding choice for building high-performance, scalable, and SEO-optimized eCommerce sites. It combines the benefits of server-side rendering, static generation, and flexible integrations, making it an adaptable solution for eCommerce brands of all sizes.
By choosing Next.js, brands like Nike, Twitch, and Hulu have demonstrated how well it can scale, handle performance demands, and secure user data in large-scale applications. For eCommerce businesses seeking an edge in a competitive market, Next.js offers the tools to deliver a top-tier shopping experience with reliable speed, security, and flexibility.
Building a high-performance eCommerce store involves a blend of design, user experience, API integration, and security features that work seamlessly together to provide a smooth, responsive shopping experience. Let’s delve deeper into the elements that make Next.js a solid foundation for creating high-quality eCommerce stores.
In eCommerce, fast loading times can significantly impact customer satisfaction and conversion rates. Studies show that even a one-second delay in page load time can lead to a considerable drop in conversions. Next.js optimizes for speed with features like:
With mobile accounting for a significant percentage of eCommerce traffic, responsive and mobile-first design is essential. Next.js supports responsive design through:
Responsive Design helps improve usability, enhance SEO, and reduce bounce rates, all crucial factors in a successful eCommerce store.
A high-performance eCommerce store isn't just about speed—it’s also about delivering an intuitive and visually appealing experience that resonates with users. Next.js supports various design and UX/UI tools that enhance the shopping experience:
Case Study: IKEA uses Three.js for its online 3D furniture configurator, providing customers with a real-time 3D view of products. This feature, integrated into an eCommerce setup, can create an engaging, immersive shopping experience.
Personalized experiences are a core driver of engagement and sales in eCommerce. Next.js’s API capabilities make it easier to integrate with personalization engines and databases for delivering dynamic, user-specific content:
Case Study: Netflix employs a similar approach, using dynamic content and personalized recommendations to enhance user engagement, helping users discover content tailored to their viewing habits.
Next.js provides secure API routes that can be used to interact with a range of third-party services, like payment processors and product management systems. This flexibility enables robust integration options:
Case Study: Glossier, a popular beauty brand, integrates with Shopify using API routes to sync inventory and manage orders, providing a reliable shopping experience that scales with demand.
Security is essential for eCommerce stores, which manage sensitive customer data, payment information, and personal details. Next.js facilitates secure development through:
Case Study: Many financial services companies use Next.js for the secure management of sensitive data, leveraging its API route protections and OAuth integrations to ensure that their platforms remain secure and user-friendly.
For eCommerce stores, visualizing products in 3D or with enhanced interactivity can lead to higher engagement and conversion rates. Next.js can integrate with advanced visualization tools and 3D libraries like:
Case Study: Nike has incorporated 3D and AR features into its app, allowing users to try on products or view them in 3D. Integrating such features with Next.js in a web environment can similarly boost engagement and interaction rates for online stores.
User experience (UX) and design quality play a pivotal role in keeping users engaged. With Next.js, developers have access to a range of UX and UI tools that streamline the design and testing process:
Testing and deployment are critical for a high-performance eCommerce store. Next.js offers:
Next.js offers a comprehensive range of tools and integrations that make it possible to build high-performance, visually rich, and secure eCommerce stores. Whether you’re creating a fast-loading storefront, integrating 3D product visuals, or implementing personalized recommendations, Next.js provides the foundation needed to elevate your online shopping experience.
Building an eCommerce store with Next.js is a rewarding process that combines powerful performance features with flexibility. Here’s a detailed, step-by-step guide on setting up your Next.js project for eCommerce, including relevant code snippets.
Setting up a Next.js project involves creating a structured environment that will support all eCommerce functionalities like product displays, checkout, and user interactions. This guide will cover initial setup, file organization, installing necessary packages, and establishing environment variables.
Before starting, ensure Node.js and NPM are installed. You can download them from nodejs.org.
Verify the installation:
node -v
npm -v
Start by creating a new Next.js project using the create-next-app
command. This command sets up the basic structure and installs dependencies like React and Next.js.
npx create-next-app@latest ecommerce-store
You’ll be prompted to name your app (in this case, ecommerce-store
). Follow the prompts to set up a new app.
Navigate into your new directory:
cd ecommerce-store
Run the development server to make sure everything is set up:
npm run dev
Visit http://localhost:3000
to confirm that your Next.js app is running.
A well-organized file structure is crucial for a scalable eCommerce store. Here’s a recommended setup:
ecommerce-store/
├── components/ # Reusable components like Navbar, Footer, etc.
├── pages/ # Route-based pages like Home, Product, Checkout
│ ├── index.js # Homepage
│ ├── product/ # Dynamic product page
│ ├── cart.js # Shopping cart page
│ └── checkout.js # Checkout page
├── public/ # Static assets (images, icons, etc.)
├── styles/ # CSS or SCSS styles
├── utils/ # Utility functions like API calls, formatters
├── .env.local # Environment variables
└── next.config.js # Next.js configuration file
For an eCommerce site, you’ll likely need environment variables to store API keys and sensitive information. Next.js supports .env.local
files for this purpose.
.env.local
file in the root directory:touch .env.local
NEXT_PUBLIC_API_URL=https://yourapiurl.com
NEXT_PUBLIC_STRIPE_API_KEY=your_stripe_key
NEXT_PUBLIC_CMS_API_KEY=your_cms_key
process.env
:const apiUrl = process.env.NEXT_PUBLIC_API_URL;
To build a fully functional eCommerce store, we’ll need some essential packages. Here are a few commonly used ones:
Install them using NPM:
npm install axios @stripe/stripe-js react-icons framer-motion
Next.js uses file-based routing, so let’s set up some basic routes for our eCommerce store, such as the homepage, product page, cart, and checkout.
1. Create a Home Page (pages/index.js
):
// pages/index.js
import Link from "next/link";
export default function Home() {
return (
<div>
<h1>Welcome to Our eCommerce Store</h1>
<p>Explore our collection of products.</p>
<Link href="/products">
<a>View Products</a>
</Link>
</div>
);
}
2. Set Up a Product Page (pages/product/[id].js
):
Next.js supports dynamic routing using brackets in the filename, such as [id]
for product IDs.
// pages/product/[id].js
import { useRouter } from "next/router";
export default function ProductPage() {
const router = useRouter();
const { id } = router.query;
return (
<div>
<h1>Product Details - {id}</h1>
<p>Description of the product...</p>
<button>Add to Cart</button>
</div>
);
}
3. Set Up a Cart Page (pages/cart.js
):
// pages/cart.js
export default function Cart() {
return (
<div>
<h1>Your Cart</h1>
<p>No items in the cart.</p>
</div>
);
}
4. Set Up a Checkout Page (pages/checkout.js
):
// pages/checkout.js
export default function Checkout() {
return (
<div>
<h1>Checkout</h1>
<p>Complete your purchase.</p>
</div>
);
}
Next, let’s create global styles. Open styles/globals.css
and add some basic CSS.
/* styles/globals.css */
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
h1,
h2,
h3,
h4,
h5,
h6 {
color: #333;
}
To ensure that these styles are globally applied, import globals.css
into pages/_app.js
.
// pages/_app.js
import "../styles/globals.css";
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export default MyApp;
Creating a layout component helps ensure that certain elements (e.g., Navbar and Footer) persist across all pages.
components/Layout.js
):// components/Layout.js
import Navbar from "./Navbar";
import Footer from "./Footer";
export default function Layout({ children }) {
return (
<div>
<Navbar />
<main>{children}</main>
<Footer />
</div>
);
}
Set Up the Navbar and Footer:
For simplicity, create two files, components/Navbar.js
and components/Footer.js
, with basic structure.
// components/Navbar.js
import Link from 'next/link';
export default function Navbar() {
return (
<nav>
<Link href="/">Home</Link> | <Link href="/cart">Cart</Link>
</nav>
);
}
// components/Footer.js
export default function Footer() {
return (
<footer>
<p>© {new Date().getFullYear()} eCommerce Store</p>
</footer>
);
}
_app.js
:// pages/_app.js
import "../styles/globals.css";
import Layout from "../components/Layout";
function MyApp({ Component, pageProps }) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
);
}
export default MyApp;
Add basic SEO metadata to the homepage using next/head
:
// pages/index.js
import Head from "next/head";
export default function Home() {
return (
<>
<Head>
<title>eCommerce Store</title>
<meta
name="description"
content="Your go-to online store for quality products."
/>
</Head>
<div>
<h1>Welcome to Our eCommerce Store</h1>
<p>Explore our collection of products.</p>
</div>
</>
);
}
Selecting the right content management system (CMS) is crucial for managing your eCommerce store’s content, updating product information, and keeping customers engaged with fresh, relevant material. Beyond Sanity, other CMS options such as Contentful, Strapi, and WordPress with WooCommerce also offer unique benefits. Here's a comparison to help you decide which CMS fits best for your store.
Each of these websites provides documentation, pricing details, and feature breakdowns to help you explore their CMS solutions further.
Sanity is a headless CMS known for its real-time editing capabilities and fully customizable interface. It's ideal for businesses that require a highly tailored eCommerce experience, offering strong developer support and robust integrations with modern frameworks like Next.js.
Contentful is another popular headless CMS that supports a wide range of integrations and offers a user-friendly interface. It’s excellent for enterprises needing scalability and is designed for structured content that adapts well to various digital experiences beyond eCommerce.
Strapi is an open-source headless CMS that allows for complete customization and flexibility in content management. It integrates smoothly with React frameworks like Next.js and offers a robust admin panel for managing eCommerce content.
WordPress, when combined with the WooCommerce plugin, is one of the most widely used CMS options for eCommerce. It’s highly customizable, with many themes, plugins, and strong SEO capabilities. However, it may require additional optimization to match the performance standards of headless CMSs like Sanity or Contentful.
Shopify can also function as a CMS in headless mode, allowing you to manage products and orders while using frameworks like Next.js for a customized front-end experience. Shopify’s backend is built for eCommerce, so it’s ideal for stores needing streamlined product management and scalability.
CMS | Pros | Cons | Pricing |
---|---|---|---|
Sanity | Real-time editing, fully customizable, strong Next.js integration | Can be costly at higher tiers; requires technical knowledge for setup | Free tier; Pro at $99/month |
Contentful | User-friendly, great for structured content, scalable | Expensive, especially for small businesses; limited customizability | Free for Community; Team at $489/month |
Strapi | Open-source, highly flexible, supports multiple databases | Self-hosting may require more technical maintenance; limited hosting options | Free self-hosted; Cloud starts at $99/month |
WordPress + WooCommerce | Huge community, thousands of plugins, cost-effective | Can be slower without optimization; security vulnerabilities without updates | Free core, plugins/themes add costs |
Shopify (Headless) | Built for eCommerce, excellent backend management, strong scalability | Limited customization without plugins; monthly fees can be high | $39/month for Basic, up to $399/month |
Each CMS offers unique benefits depending on your store’s needs and budget. Here’s a quick guide on how to choose:
Prateeksha Web Design specializes in helping small businesses leverage the power of these CMS platforms, integrating them seamlessly with Next.js for a customized, high-performance eCommerce experience.
Setting up a payment gateway is essential for an eCommerce store to process payments securely and smoothly. There are several payment gateway options available, each with unique features, pros, cons, and pricing. Here’s an overview of popular payment gateways, along with details on their integration, pros and cons, and links to documentation.
Website: Stripe.com
Documentation: Stripe API Documentation
Stripe is a popular choice for eCommerce due to its ease of integration, extensive API, and support for a wide range of payment methods. Stripe offers a robust dashboard for managing payments, refunds, and subscriptions.
Install Stripe’s Node.js library:
npm install @stripe/stripe-js
npm install stripe
Set up the Stripe configuration in your .env.local
file with your secret keys:
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=your_publishable_key
STRIPE_SECRET_KEY=your_secret_key
Initialize Stripe in your Next.js project:
// utils/stripe.js
import { loadStripe } from "@stripe/stripe-js";
export const stripePromise = loadStripe(
process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
);
Create a Checkout Button Component:
// components/CheckoutButton.js
import { stripePromise } from "../utils/stripe";
const CheckoutButton = ({ priceId }) => {
const handleCheckout = async () => {
const stripe = await stripePromise;
await stripe.redirectToCheckout({ sessionId: "session_id_from_server" });
};
return <button onClick={handleCheckout}>Checkout</button>;
};
export default CheckoutButton;
Website: PayPal.com
Documentation: PayPal Developer Documentation
PayPal is a widely recognized payment gateway trusted by customers globally. It provides options for express checkout, credit card processing, and PayPal balance payments.
Install PayPal SDK:
npm install @paypal/react-paypal-js
Add PayPal Client ID in Environment Variables:
NEXT_PUBLIC_PAYPAL_CLIENT_ID=your_paypal_client_id
Create a PayPal Button Component:
// components/PayPalButton.js
import {
PayPalScriptProvider,
PayPalButtons,
} from "@paypal/react-paypal-js";
export default function PayPalButton() {
return (
<PayPalScriptProvider
options={{ "client-id": process.env.NEXT_PUBLIC_PAYPAL_CLIENT_ID }}
>
<PayPalButtons
createOrder={(data, actions) => {
return actions.order.create({
purchase_units: [{ amount: { value: "10.00" } }],
});
}}
onApprove={(data, actions) => {
return actions.order.capture().then((details) => {
alert(
"Transaction completed by " + details.payer.name.given_name
);
});
}}
/>
</PayPalScriptProvider>
);
}
Website: Squareup.com
Documentation: Square Developer Documentation
Square is a popular payment processor for small to medium-sized businesses, offering a unified platform for both online and in-store transactions. Square’s APIs enable integrations for online payments, in-app payments, and POS (point of sale).
Install the Square SDK:
npm install @square/web-sdk
Configure Environment Variables:
NEXT_PUBLIC_SQUARE_APPLICATION_ID=your_application_id
SQUARE_ACCESS_TOKEN=your_access_token
Create a Payment Component:
Square provides documentation for integrating the Square Web Payments SDK to create payment flows.
Website: Authorize.net
Documentation: Authorize.Net API Documentation
Authorize.Net is known for its robust Fraud Prevention tools and advanced API capabilities. It’s widely used for businesses that require secure and customizable payment solutions.
Install the Authorize.Net SDK:
npm install authorizenet
Set Up API Credentials in Environment Variables:
NEXT_PUBLIC_AUTH_NET_API_KEY=your_api_key
Create a Payment Component:
Integration with Authorize.Net requires server-side implementations for secure transactions.
Website: Adyen.com
Documentation: Adyen API Documentation
Adyen is a high-end payment processor used by large companies for international transactions. It provides a robust API, supports multiple currencies, and integrates with many payment methods.
Install Adyen’s Node.js Client Library:
npm install @adyen/api-library
Configure Adyen API:
Place Adyen’s environment variables in your .env.local
file.
Create a Payment Component:
Adyen requires a server-side setup, so refer to their API documentation for implementing secure payment handling.
Payment Gateway | Pros | Cons | Website | Fees (per transaction) |
---|---|---|---|---|
Stripe | Supports a wide range of payment methods, developer-friendly, scalable | Higher fees for international, limited offline support | Stripe | 2.9% + 30¢ |
PayPal | Trusted brand, offers PayPal balance payments, fast checkout option | Redirects users, higher fees for international payments | PayPal | 2.9% + 30¢ |
Square | Unified online/offline solution, strong POS integration | Limited international availability | Square | 2.6% + 10¢ |
Authorize.Net | Advanced fraud prevention, ideal for B2B and high-value transactions | Monthly fees, complex setup | Authorize.Net | $25/month + 2.9% + 30¢ |
Adyen | Global support, extensive fraud tools, supports numerous currencies | High setup fees, complex integration, best for large businesses | Adyen | Varies, custom fees based on volume |
Each payment gateway has its own unique strengths:
Product Management in Next.js
Managing products in an eCommerce store requires efficient handling of product details, inventory levels, categorization, pricing, and availability. With Next.js’s API integration capabilities, product management becomes streamlined, allowing for real-time updates and easy handling of large catalogs. By integrating with a backend CMS (like Sanity or Contentful) or an eCommerce platform (like Shopify), you can create a dynamic, responsive product catalog that updates instantly whenever changes occur in the backend.
Here’s a step-by-step guide, including code examples, for managing products in Next.js with API integration.
You’ll first need a data source for your products. Common options include:
For this example, let’s use Shopify as the backend for product data and Next.js for the frontend, displaying products and updating inventory in real-time.
To interact with the Shopify API, you’ll need a Storefront Access Token, which you can obtain from your Shopify admin panel.
Create a .env.local
file in your project’s root directory to store environment variables securely.
NEXT_PUBLIC_SHOPIFY_STORE_URL=your-shopify-store.myshopify.com
NEXT_PUBLIC_SHOPIFY_ACCESS_TOKEN=your_storefront_access_token
Access the environment variables in your code using process.env
.
Create a helper function to handle API calls to Shopify. This function will fetch products using the Storefront API.
Create a new file utils/shopify.js
:
// utils/shopify.js
const domain = process.env.NEXT_PUBLIC_SHOPIFY_STORE_URL;
const storefrontAccessToken = process.env.NEXT_PUBLIC_SHOPIFY_ACCESS_TOKEN;
async function fetchShopifyData(query) {
const URL = `https://${domain}/api/2021-04/graphql.json`;
const response = await fetch(URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Shopify-Storefront-Access-Token": storefrontAccessToken,
},
body: JSON.stringify({ query }),
});
const json = await response.json();
if (json.errors) {
throw new Error("Failed to fetch data from Shopify");
}
return json.data;
}
export async function getAllProducts() {
const query = `
{
products(first: 25) {
edges {
node {
id
title
description
priceRange {
minVariantPrice {
amount
currencyCode
}
}
images(first: 5) {
edges {
node {
src
altText
}
}
}
}
}
}
}
`;
return fetchShopifyData(query);
}
This helper function, getAllProducts
, queries Shopify’s GraphQL API to fetch products, including id
, title
, description
, price
, and images
.
Next, create a component to display the products fetched from Shopify.
Create a Product Listing Page in pages/products.js
:
// pages/products.js
import { useEffect, useState } from "react";
import { getAllProducts } from "../utils/shopify";
export default function Products() {
const [products, setProducts] = useState([]);
useEffect(() => {
async function fetchProducts() {
const data = await getAllProducts();
setProducts(data.products.edges);
}
fetchProducts();
}, []);
return (
<div>
<h1>Our Products</h1>
<div className="products-grid">
{products.map(({ node }) => (
<div key={node.id} className="product-card">
<img
src={node.images.edges[0]?.node.src}
alt={node.images.edges[0]?.node.altText}
/>
<h2>{node.title}</h2>
<p>{node.description}</p>
<p>
${node.priceRange.minVariantPrice.amount}{" "}
{node.priceRange.minVariantPrice.currencyCode}
</p>
</div>
))}
</div>
</div>
);
}
Add Basic Styling for product cards in styles/globals.css
:
/* styles/globals.css */
.products-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1.5rem;
}
.product-card {
border: 1px solid #ddd;
padding: 1rem;
text-align: center;
}
.product-card img {
max-width: 100%;
height: auto;
}
To keep inventory accurate in real time, Next.js can revalidate data on the server using Incremental Static Regeneration (ISR).
Enable ISR by modifying the getStaticProps
function:
// pages/products.js
import { getAllProducts } from "../utils/shopify";
export async function getStaticProps() {
const data = await getAllProducts();
return {
props: {
products: data.products.edges,
},
revalidate: 60, // Revalidate data every 60 seconds
};
}
export default function Products({ products }) {
return (
<div>
<h1>Our Products</h1>
<div className="products-grid">
{products.map(({ node }) => (
<div key={node.id} className="product-card">
<img
src={node.images.edges[0]?.node.src}
alt={node.images.edges[0]?.node.altText}
/>
<h2>{node.title}</h2>
<p>{node.description}</p>
<p>
${node.priceRange.minVariantPrice.amount}{" "}
{node.priceRange.minVariantPrice.currencyCode}
</p>
</div>
))}
</div>
</div>
);
}
The revalidate: 60
option enables ISR, meaning the data will refresh every 60 seconds. This keeps product data up-to-date without requiring a full rebuild.
Adding search and filtering capabilities makes it easier for customers to find products.
Create Search and Filter Functionality:
// pages/products.js
import { useState } from "react";
import { getAllProducts } from "../utils/shopify";
export async function getStaticProps() {
const data = await getAllProducts();
return {
props: {
products: data.products.edges,
},
revalidate: 60,
};
}
export default function Products({ products }) {
const [search, setSearch] = useState("");
const [filteredProducts, setFilteredProducts] = useState(products);
const handleSearch = (event) => {
const query = event.target.value.toLowerCase();
setSearch(query);
const filtered = products.filter(({ node }) =>
node.title.toLowerCase().includes(query)
);
setFilteredProducts(filtered);
};
return (
<div>
<h1>Our Products</h1>
<input
type="text"
placeholder="Search products..."
value={search}
onChange={handleSearch}
style={{ padding: "0.5rem", marginBottom: "1rem" }}
/>
<div className="products-grid">
{filteredProducts.map(({ node }) => (
<div key={node.id} className="product-card">
<img
src={node.images.edges[0]?.node.src}
alt={node.images.edges[0]?.node.altText}
/>
<h2>{node.title}</h2>
<p>{node.description}</p>
<p>
${node.priceRange.minVariantPrice.amount}{" "}
{node.priceRange.minVariantPrice.currencyCode}
</p>
</div>
))}
</div>
</div>
);
}
The handleSearch
function filters products based on the input and updates filteredProducts
accordingly, creating a responsive search experience.
This setup provides a scalable and responsive product management system using Next.js and Shopify. By leveraging Next.js’s API integration capabilities, you can:
This setup can be extended with more complex filters, pagination, and sorting as the store grows.
Implementing shopping cart functionality in a Next.js eCommerce app requires creating a way to manage cart items and quantities, which can be done effectively using React’s built-in state management or a library like Context API. Here’s a step-by-step guide for implementing a shopping cart using Context API for managing the state across the app.
First, create a new context for the cart to store items and handle updates.
Create a new file called CartContext.js
in a context
folder (e.g., context/CartContext.js
).
// context/CartContext.js
import { createContext, useContext, useState } from "react";
const CartContext = createContext();
export function CartProvider({ children }) {
const [cartItems, setCartItems] = useState([]);
const addToCart = (product) => {
setCartItems((prevItems) => {
const itemExists = prevItems.find((item) => item.id === product.id);
if (itemExists) {
return prevItems.map((item) =>
item.id === product.id
? { ...item, quantity: item.quantity + 1 }
: item
);
} else {
return [...prevItems, { ...product, quantity: 1 }];
}
});
};
const removeFromCart = (id) => {
setCartItems((prevItems) => prevItems.filter((item) => item.id !== id));
};
const clearCart = () => {
setCartItems([]);
};
const updateQuantity = (id, quantity) => {
setCartItems((prevItems) =>
prevItems.map((item) =>
item.id === id ? { ...item, quantity } : item
)
);
};
return (
<CartContext.Provider
value={{
cartItems,
addToCart,
removeFromCart,
clearCart,
updateQuantity,
}}
>
{children}
</CartContext.Provider>
);
}
export function useCart() {
return useContext(CartContext);
}
This code defines a CartProvider
component that will wrap your app and provide cart state to all components within. It includes functions to:
addToCart
)removeFromCart
)updateQuantity
)clearCart
)Next, you’ll need to wrap the entire app in the CartProvider
so that the cart state is available in any component.
Open _app.js
and wrap your application with CartProvider
.
// pages/_app.js
import "../styles/globals.css";
import { CartProvider } from "../context/CartContext";
function MyApp({ Component, pageProps }) {
return (
<CartProvider>
<Component {...pageProps} />
</CartProvider>
);
}
export default MyApp;
Now, all components in the app will have access to the cart context.
Create a component to show the items in the cart.
Create a new file called Cart.js
in the components
folder.
// components/Cart.js
import { useCart } from "../context/CartContext";
export default function Cart() {
const { cartItems, removeFromCart, updateQuantity, clearCart } = useCart();
return (
<div>
<h2>Shopping Cart</h2>
{cartItems.length === 0 ? (
<p>Your cart is empty.</p>
) : (
<>
<ul>
{cartItems.map((item) => (
<li key={item.id}>
<h3>{item.title}</h3>
<p>Price: ${item.price}</p>
<p>
Quantity:
<input
type="number"
value={item.quantity}
min="1"
onChange={(e) =>
updateQuantity(item.id, parseInt(e.target.value, 10))
}
/>
</p>
<button onClick={() => removeFromCart(item.id)}>
Remove
</button>
</li>
))}
</ul>
<button onClick={clearCart}>Clear Cart</button>
</>
)}
</div>
);
}
This component uses useCart
to access cart items and display each item with options to update quantity, remove items, or clear the cart.
On each product page, you’ll need a button to add items to the cart. This button will call the addToCart
function from the context.
Update your product component (e.g., ProductPage.js
or Product.js
) to include an "Add to Cart" button.
// pages/product/[id].js
import { useRouter } from "next/router";
import { useCart } from "../../context/CartContext";
export default function ProductPage({ product }) {
const router = useRouter();
const { addToCart } = useCart();
if (router.isFallback) return <div>Loading...</div>;
return (
<div>
<h1>{product.title}</h1>
<p>{product.description}</p>
<p>Price: ${product.price}</p>
<button onClick={() => addToCart(product)}>Add to Cart</button>
</div>
);
}
export async function getStaticPaths() {
// Fetch product IDs to generate paths (replace with actual product fetching code)
const paths = [{ params: { id: "1" } }];
return { paths, fallback: true };
}
export async function getStaticProps({ params }) {
// Fetch single product data (replace with actual fetching code)
const product = {
id: params.id,
title: "Sample Product",
price: 10,
description: "This is a sample product.",
};
return { props: { product } };
}
In this example, addToCart(product)
will add the selected product to the cart with a default quantity of 1.
To give users easy access to the cart, you can add a cart icon in the navigation bar, showing the number of items in the cart.
Update the Navbar Component to include a cart icon and display the cart item count.
// components/Navbar.js
import Link from "next/link";
import { useCart } from "../context/CartContext";
export default function Navbar() {
const { cartItems } = useCart();
const itemCount = cartItems.reduce(
(count, item) => count + item.quantity,
0
);
return (
<nav>
<Link href="/">Home</Link>
<Link href="/products">Products</Link>
<Link href="/cart">
<a>Cart ({itemCount})</a>
</Link>
</nav>
);
}
This code calculates the total item count in the cart and displays it next to the “Cart” link.
Finally, create a dedicated page to view the cart.
Create a Cart Page in pages/cart.js
to render the Cart
component.
// pages/cart.js
import Cart from "../components/Cart";
export default function CartPage() {
return (
<div>
<h1>Your Cart</h1>
<Cart />
</div>
);
}
With this setup, you have:
CartContext.js
)This setup provides a simple and extendable shopping cart functionality with state management using the Context API, making it accessible throughout the Next.js application.
getStaticProps
and getServerSideProps
, to ensure the latest data is displayed.next/head
to include meta tags for page titles, descriptions, and canonical links. This improves the store’s visibility in search engines.For eCommerce stores looking to leverage Shopify’s backend while maintaining Next.js’s frontend flexibility, integrating Shopify can be a game-changer.
Shopify offers powerful product management and order processing capabilities, while Next.js provides a fast, customizable frontend experience.
Prateeksha Web Design specializes in Shopify integrations with Next.js, helping businesses combine the best of both worlds. From design to development, our services ensure a smooth integration that optimizes both frontend performance and backend management.
With Next.js, your eCommerce store is prepared for future advancements in web technology. Next.js’s flexibility allows for continuous updates and improvements to keep up with evolving market demands and trends. Prateeksha Web Design’s expertise extends beyond initial setup, offering ongoing support to help small businesses adapt to changing industry standards and maintain an optimized online presence.
Conclusion
Building a high-performance eCommerce store with Next.js is an excellent way to create an engaging, fast, and scalable online shopping experience. By leveraging Next.js’s strengths in performance, SEO, and flexibility, businesses can stay ahead in a competitive market. With Prateeksha Web Design’s expertise in web design, Shopify integration, and digital marketing, small businesses have the resources they need to grow and optimize their online stores effectively.
If you're ready to create a high-performance eCommerce store, reach out to Prateeksha Web Design. Let us help you build a store that not only attracts visitors but turns them into loyal customers, maximizing your online potential and securing your place in the digital market.
Prateeksha Web Design Company offers a comprehensive range of services to develop high-performance eCommerce stores using Next.js. They leverage the power of this open-source development framework to deliver enhanced user experiences, faster page load times, and better SEO outcomes. Prateeksha's team of experts ensures secure, scalable, and SEO-friendly eCommerce solutions for businesses of all sizes.
Interested in learning more? Contact us today.