Build With Abdallah logo Build With Abdallah Software · AI · Automation
Tutorial 7 min read Jun 08, 2026

Building a Server-Side Rendered E-commerce Site with Next.js 16 and React 19

In today's fastpaced digital world, delivering a fast and efficient user experience is crucial for ecommerce platforms. Serverside rendering (SSR) with Next.js provides a way to en

A
Abdallah Mohamed
Senior Full-Stack Engineer
Building a Server-Side Rendered E-commerce Site with Next.js 16 and React 19

Building a Server-Side Rendered E-commerce Site with Next.js 16 and React 19

In today's fast-paced digital world, delivering a fast and efficient user experience is crucial for e-commerce platforms. Server-side rendering (SSR) with Next.js provides a way to enhance the performance of web applications by pre-rendering pages on the server, improving load times and SEO. With the recent release of Next.js 16 and React 19, developers can leverage the latest features and improvements to build modern, scalable e-commerce sites.

This tutorial will guide you through the process of building a server-side rendered e-commerce site using Next.js 16 and React 19. We will cover setting up the project, building essential components, and fetching data from an API.

Prerequisites

Before we start, ensure you have the following installed on your machine:

  1. Node.js (version 18 or later)

    # Check if Node.js is installed
    node -v
    
    # If not installed, use nvm to install Node.js 18
    nvm install 18
    nvm use 18
    
  2. npm (comes with Node.js)

    # Check if npm is installed
    npm -v
    
  3. Next.js and React (will be installed as part of the project setup)

    # Install Next.js and React in your project
    npx create-next-app@16 my-ecommerce-site
    cd my-ecommerce-site
    

Project Structure

Once you have set up your project, your directory structure should look like this:

my-ecommerce-site/
├── node_modules/
├── public/
│   ├── favicon.ico
│   └── vercel.svg
├── styles/
│   ├── globals.css
│   └── Home.module.css
├── pages/
│   ├── api/
│   │   └── hello.js
│   ├── _app.js
│   ├── index.js
│   └── product.js
├── .gitignore
├── package.json
└── README.md

Step 1: Setting Up the Home Page

First, we will set up the home page of our e-commerce site. This page will serve as the landing page for our users.

Create a new file index.js inside the pages directory:

// pages/index.js

import React from 'react';

export default function Home() {
  return (
    <div>
      <h1>Welcome to My E-commerce Site</h1>
      <p>Discover our range of products.</p>
    </div>
  );
}

This code defines a simple functional component that renders a welcome message. The Home component will be the default export from the index.js file, making it the landing page of our site.

Step 2: Creating a Product Page

Next, we will create a product page that will display individual product details. This page will be server-side rendered.

Create a new file product.js inside the pages directory:

// pages/product.js

import React from 'react';

export async function getServerSideProps(context) {
  const { id } = context.query;
  const res = await fetch(`https://fakestoreapi.com/products/${id}`);
  const product = await res.json();

  return {
    props: { product },
  };
}

export default function Product({ product }) {
  return (
    <div>
      <h1>{product.title}</h1>
      <p>{product.description}</p>
      <p>Price: ${product.price}</p>
    </div>
  );
}

In this code, the getServerSideProps function fetches product data from a fake store API based on the product ID from the query parameters. This data is passed as props to the Product component, which then renders the product details.

Step 3: Adding Global Styles

To maintain a consistent look and feel across the site, we will add some global styles.

Open the globals.css file in the styles directory and add the following CSS:

/* styles/globals.css */

body {
  font-family: 'Arial', sans-serif;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

h1 {
  color: #333;
}

p {
  color: #666;
}

div {
  padding: 20px;
}

These styles set up a basic font and color scheme for the site. The body style ensures a consistent font across all pages, while the h1 and p styles define the text color. The div style adds padding to the content areas.

By completing these steps, we have set up the foundational structure of our e-commerce site. In the next part of this tutorial, we will expand the functionality by adding more components and integrating a shopping cart feature.

Step 4: Integrating a Shopping Cart Feature

To enhance our e-commerce site, we will add a shopping cart feature. This will allow users to add products to their cart and view the cart's contents.

Creating a Cart Context

First, we need to create a context to manage the cart's state globally across the application. Create a new file CartContext.js inside a new directory called context:

// context/CartContext.js

import React, { createContext, useState, useContext } from 'react';

const CartContext = createContext();

export function useCart() {
  return useContext(CartContext);
}

export function CartProvider({ children }) {
  const [cart, setCart] = useState([]);

  const addToCart = (product) => {
    setCart((prevCart) => [...prevCart, product]);
  };

  const removeFromCart = (productId) => {
    setCart((prevCart) => prevCart.filter(product => product.id !== productId));
  };

  return (
    <CartContext.Provider value={{ cart, addToCart, removeFromCart }}>
      {children}
    </CartContext.Provider>
  );
}

Wrapping the Application with CartProvider

Next, wrap the application in the CartProvider to provide access to the cart context throughout the app. Modify the _app.js file in the pages directory:

// pages/_app.js

import '../styles/globals.css';
import { CartProvider } from '../context/CartContext';

function MyApp({ Component, pageProps }) {
  return (
    <CartProvider>
      <Component {...pageProps} />
    </CartProvider>
  );
}

export default MyApp;

Adding Cart Functionality to the Product Page

Now, let's update the product page to allow adding items to the cart:

// pages/product.js

import React from 'react';
import { useCart } from '../context/CartContext';

export async function getServerSideProps(context) {
  const { id } = context.query;
  const res = await fetch(`https://fakestoreapi.com/products/${id}`);
  const product = await res.json();

  return {
    props: { product },
  };
}

export default function Product({ product }) {
  const { addToCart } = useCart();

  return (
    <div>
      <h1>{product.title}</h1>
      <p>{product.description}</p>
      <p>Price: ${product.price}</p>
      <button onClick={() => addToCart(product)}>Add to Cart</button>
    </div>
  );
}

Step 5: Creating a Cart Page

Finally, let's create a cart page to display the products added to the cart.

Create a new file cart.js inside the pages directory:

// pages/cart.js

import React from 'react';
import { useCart } from '../context/CartContext';

export default function Cart() {
  const { cart, removeFromCart } = useCart();

  return (
    <div>
      <h1>Your Shopping Cart</h1>
      {cart.length === 0 ? (
        <p>Your cart is empty</p>
      ) : (
        cart.map((product) => (
          <div key={product.id}>
            <h2>{product.title}</h2>
            <p>Price: ${product.price}</p>
            <button onClick={() => removeFromCart(product.id)}>Remove</button>
          </div>
        ))
      )}
    </div>
  );
}

Complete Working Example

Below is the complete list of files and their contents for the final working e-commerce site:

pages/index.js

import React from 'react';

export default function Home() {
  return (
    <div>
      <h1>Welcome to My E-commerce Site</h1>
      <p>Discover our range of products.</p>
    </div>
  );
}

pages/product.js

import React from 'react';
import { useCart } from '../context/CartContext';

export async function getServerSideProps(context) {
  const { id } = context.query;
  const res = await fetch(`https://fakestoreapi.com/products/${id}`);
  const product = await res.json();

  return {
    props: { product },
  };
}

export default function Product({ product }) {
  const { addToCart } = useCart();

  return (
    <div>
      <h1>{product.title}</h1>
      <p>{product.description}</p>
      <p>Price: ${product.price}</p>
      <button onClick={() => addToCart(product)}>Add to Cart</button>
    </div>
  );
}

pages/cart.js

import React from 'react';
import { useCart } from '../context/CartContext';

export default function Cart() {
  const { cart, removeFromCart } = useCart();

  return (
    <div>
      <h1>Your Shopping Cart</h1>
      {cart.length === 0 ? (
        <p>Your cart is empty</p>
      ) : (
        cart.map((product) => (
          <div key={product.id}>
            <h2>{product.title}</h2>
            <p>Price: ${product.price}</p>
            <button onClick={() => removeFromCart(product.id)}>Remove</button>
          </div>
        ))
      )}
    </div>
  );
}

pages/_app.js

import '../styles/globals.css';
import { CartProvider } from '../context/CartContext';

function MyApp({ Component, pageProps }) {
  return (
    <CartProvider>
      <Component {...pageProps} />
    </CartProvider>
  );
}

export default MyApp;

context/CartContext.js

import React, { createContext, useState, useContext } from 'react';

const CartContext = createContext();

export function useCart() {
  return useContext(CartContext);
}

export function CartProvider({ children }) {
  const [cart, setCart] = useState([]);

  const addToCart = (product) => {
    setCart((prevCart) => [...prevCart, product]);
  };

  const removeFromCart = (productId) => {
    setCart((prevCart) => prevCart.filter(product => product.id !== productId));
  };

  return (
    <CartContext.Provider value={{ cart, addToCart, removeFromCart }}>
      {children}
    </CartContext.Provider>
  );
}

styles/globals.css

body {
  font-family: 'Arial', sans-serif;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

h1 {
  color: #333;
}

p {
  color: #666;
}

div {
  padding: 20px;
}

Common Errors and Fixes

  1. Error: TypeError: Cannot read property 'id' of undefined

    Fix: Ensure that the product object is correctly defined when adding to or removing from the cart. Check if the id is correctly passed from the product data.

  2. Error: fetch is not defined

    Fix: Ensure that you are using fetch within server-side functions like getServerSideProps. If using fetch on the client-side, ensure the environment supports it or use a polyfill.

  3. Error: Cannot find module '../context/CartContext'

    Fix: Verify that the path to CartContext is correct and matches the file structure. Ensure the file is correctly named and located in the context directory.

Conclusion

In this tutorial, we built a server-side rendered e-commerce site using Next.js 16 and React 19. We covered setting up the project, creating essential pages, and integrating a shopping cart feature. This foundational setup can be expanded with additional features such as user authentication and payment processing.

Sources