Build and deploy a Next.js ecommerce website in 5 steps
Tags: nextjs, headlesscms, react
Published: 2024-05-02 15:51:08

---
title: Build and deploy a Next.js ecommerce website in 5 steps
published: true
description: In this article, I'm going to show you how to build and deploy an ecommerce website in 5 steps. We will cover installing the Cosmic ecommerce Block, connecting Stripe, and deploying to a website hosting service.
tags: Nextjs, HeadlessCMS, React
cover_image: https://imgix.cosmicjs.com/f7c7ca30-0801-11ef-9eca-7d347081a9fb-store.png?w=1000&auto=format&dpr=2
# Use a ratio of 100:42 for best results.
# published_at: 2024-05-02 15:41 +0000
canonical_url: https://www.cosmicjs.com/blog/build-and-deploy-a-nextjs-ecommerce-website-in-5-steps
---

In this article, I'm going to show you how to build and deploy an ecommerce website in 5 steps.  By leveraging the Cosmic React component library [Blocks](https://blocks.cosmicjs.com/), we can build a high performance ecommerce website ready to accept product purchases in a matter of minutes. Let's go.
![ecommerce-production.png](https://imgix.cosmicjs.com/fa0c8d70-082a-11ef-9eca-7d347081a9fb-ecommerce-production.png?w=2000&auto=format,compression)

## 1. Install the Cosmic ecommerce Block
Start by installing a new Next.js app. Run the following command in your terminal application.
```bash
bunx create-next-app@latest cosmic-ecommerce && cd cosmic-ecommerce
```
Make sure to set the options to the following:![project-options.png](https://imgix.cosmicjs.com/67d622c0-07fa-11ef-9eca-7d347081a9fb-project-options.png?w=2000&auto=format,compression)

Next, [log in to Cosmic](https://app.cosmicjs.com/login) and create a new empty Project. 
![create-ecommerce-project.png](https://imgix.cosmicjs.com/ea221240-07f8-11ef-9eca-7d347081a9fb-create-ecommerce-project.png?w=2000&auto=format,compression)

Go to *Project > Extensions* and install the [Cosmic Blocks extension](https://www.cosmicjs.com/marketplace/extensions/blocks). Find the ecommerce Block.
![find-ecommerce-block.png](https://imgix.cosmicjs.com/5a39c000-07f9-11ef-9eca-7d347081a9fb-find-ecommerce-block.png?w=2000&auto=format,compression)

Follow the steps to install the Block content which includes content model and demo content. 
![install-ecommerce-block.png](https://imgix.cosmicjs.com/5a383960-07f9-11ef-9eca-7d347081a9fb-install-ecommerce-block.png?w=2000&auto=format,compression)

Then run the command to install the ecommerce components in your codebase.
```bash
bunx @cosmicjs/blocks add ecommerce image-gallery
```

Create a new `.env.local` file and add your Cosmic API keys found in the Cosmic dashboard at *Project > API keys*:
```
# .env.local
COSMIC_BUCKET_SLUG=your_cosmic_bucket_slug
COSMIC_READ_KEY=your_cosmic_read_key
COSMIC_WRITE_KEY=your_cosmic_write_key
```

To create a shop page, add a new file located at `app/shop/page.tsx` with the following:
```jsx
// app/shop/page.tsx
import { ProductList } from "@/cosmic/blocks/ecommerce/ProductList";
export default async function Shop() {
  return (
    <ProductList
      query={{ type: "products" }}
    />
  );
}
```

To create single product pages, add a new file located at `app/shop/[slug]/page.tsx` with the following:
```jsx
// app/shop/[slug]/page.tsx
import { SingleProduct } from "@/cosmic/blocks/ecommerce/SingleProduct"
export default async function SingleProductPage({
  params,
  searchParams
}: {
    params: { slug: string }
    searchParams: {
      success?: string
    }
  }) {
  return (
    <SingleProduct
      query={{ slug: params.slug, type: "products" }}
      purchased={searchParams.success ? true : false}
    />
  );
}
```

Run the app to see the progress so far:
```bash
bun dev
```

You should see the store available at `http://localhost:3000/shop` (but not yet able to checkout with Stripe).

## 2. Configure Stripe
Next, we will enable checkout and payment processing through [Stripe](https://stripe.com). First, install the Stripe clients with the following command:
```bash
bun add stripe @stripe/stripe-js
```

Add your Stripe API keys to the `.env.local` file. Find your Stripe API keys in the [Stripe dashboard](https://dashboard.stripe.com/login).
```
// .env.local
...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=change_to_your_stripe_public_key
STRIPE_SECRET_KEY=change_to_your_stripe_secret_key
```

Next, update your `app/layout.tsx` file to include the CartProvider to the layout.  (Note: this assumes you've already added the [Layout Block](https://blocks.cosmicjs.com/blocks/layout)).
```jsx
// app/layout.tsx
import "./globals.css";
import { Header } from "@/components/Header";
import { Footer } from "@/components/Footer";
import { CartProvider } from "@/cosmic/blocks/ecommerce/CartProvider";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <CartProvider>
          <Header />
          {children}
          <Footer />
        </CartProvider>
      </body>
    </html>
  );
}    
```
Next, let's add the checkout component to `components/Header.tsx`.

```jsx
// components/Header.tsx
import Link from "next/link";
import { cosmic } from "@/cosmic/client";
import { NavMenu } from "@/cosmic/blocks/navigation-menu/NavMenu";
import { CheckOut } from "@/cosmic/blocks/ecommerce/CheckOut";

export async function Header() {
  // Header data
  const { object: settings } = await cosmic.objects
    .findOne({
      type: "global-settings",
      slug: "settings",
    })
    .props("metadata")
    .depth(1);

  return (
    <div className="space-x-4 sticky top-0 bg-white/20 dark:bg-black/20 backdrop-blur-lg py-2 w-full z-[9999]">
      <div className="m-auto flex items-center md:container justify-between pl-2 pr-4">
        <Link href="/">
          <img
            src={`${settings.metadata.logo.imgix_url}?w=500&auto=format,compression`}
            alt={settings.metadata.company}
            className="h-10 m-auto dark:hidden"
          />
          <img
            src={`${settings.metadata.dark_logo.imgix_url}?w=500&auto=format,compression`}
            alt={settings.metadata.company}
            className="h-10 m-auto hidden dark:block"
          />
        </Link>
        <NavMenu query={{ type: "navigation-menus", slug: "header" }} />
        <CheckOut className="ml-4" productPath={"/shop"} />
      </div>
    </div>
  );
}
```

Next, let's add the checkout API route to our Next.js app located at `app/api/checkout/route.ts` with the following:
```jsx
// app/api/checkout/route.ts
import { type NextRequest, NextResponse } from "next/server";
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);

export async function POST(request: NextRequest) {
  const res = await request.json();
  const stripe_product_ids = res.stripe_product_ids;
  try {
    let line_items = [];
    let mode = "payment";
    for (const stripe_product_id of stripe_product_ids) {
      const product = await stripe.products.retrieve(stripe_product_id);
      const price = await stripe.prices.retrieve(product.default_price);
      line_items.push({
        price: price.id,
        quantity: 1,
      });
      // If any items are recurring
      if (price.type === "recurring") mode = "subscription";
    }
    const session = await stripe.checkout.sessions.create({
      line_items,
      mode,
      success_url: `${res.redirect_url}/?success=true`,
      cancel_url: `${res.redirect_url}/?canceled=true`,
    });
    return Response.json({ url: session.url });
  } catch (err) {
    return NextResponse.json(err, { status: 500 });
  }
}
```

## 3. Install Stripe extension
Next, go to *Project > Extensions* in the Cosmic dashboard and install the [Stripe Products Extension](https://www.cosmicjs.com/integrations/stripe). This will enable the connection between the products in Cosmic and Stripe. After installing the extension to your Project, follow the steps to add your Stripe secret key to the extension configuration.
![stripe-extension.png](https://imgix.cosmicjs.com/77dd1ce0-07fb-11ef-9eca-7d347081a9fb-stripe-extension.png?w=2000&auto=format,compression)

## 4. Add products to Stripe
After installing the Stripe Products Extension, you should now see a button on the Product page to add the product to Stripe.
![stripe-extension-product.png](https://imgix.cosmicjs.com/56380680-07fc-11ef-9eca-7d347081a9fb-stripe-extension-product.png?w=2000&auto=format,compression)
Click this button to sync your Product data to Stripe including title, image, price, and option for recurring payments (subscription).

Next, go back to your app running locally and see that the checkout is now working on any product that has been connected with Stripe (you may need to refresh the page).
<video width="500" height="350" autoplay playsinline loop muted>
    <source src="https://cdn.cosmicjs.com/78dbb640-07fd-11ef-9eca-7d347081a9fb-checkout-stripe.mp4" type="video/mp4">
  </video>

## 5. Deploy to your website hosting provider
Next, we'll deploy our ecommerce website to [Vercel](https://vercel.com) (which is a great choice to host your Next.js website). Other hosting options include [Netlify](https://www.netlify.com/) and [Render](https://render.com/).

First, [create a new git repository in GitHub](https://github.com/new) and follow the steps to push your Next.js ecommerce website code.
![new-repo.png](https://imgix.cosmicjs.com/ddb10160-07fd-11ef-9eca-7d347081a9fb-new-repo.png?w=2000&auto=format,compression)

After you have pushed your code to the repository, go to the Vercel dashboard and [add a new project](https://vercel.com/new) connected to the code repository you just created in GitHub. (Note: This requires you to enable Vercel to access your GitHub repository.)

Then add your environment variables located in your `.env.local` file. Tip: You can add the full contents of the `.env.local` file by copy / pasting it into the first field in the Vercel form.
![vercel-env-vars.png](https://imgix.cosmicjs.com/d1a87320-07fe-11ef-9eca-7d347081a9fb-vercel-env-vars.png?w=2000&auto=format,compression)

Now deploy your code. 🚀

You should now see a production build of your ecommerce website ready to take payments for your products and services. 💰
![ecommerce-production.png](https://imgix.cosmicjs.com/fa0c8d70-082a-11ef-9eca-7d347081a9fb-ecommerce-production.png?w=2000&auto=format,compression)


## Next steps
I hope you enjoyed this quick tutorial on building an ecommerce website with Cosmic Blocks, Stripe, and Vercel. Check out [more Blocks to explore](https://blocks.cosmicjs.com/) to help you build optimized web experiences faster.

If you have any questions, [reach out to me on X (fka Twitter)](https://twitter.com/tonyspiro) or on the [Cosmic Discord server](https://discord.gg/MSCwQ7D6Mg).