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, we can build a high performance ecommerce website ready to accept product purchases in a matter of minutes. Let's go.
1. Install the Cosmic ecommerce Block
Start by installing a new Next.js app. Run the following command in your terminal application.
bunx create-next-app@latest cosmic-ecommerce && cd cosmic-ecommerce
Make sure to set the options to the following:
Next, log in to Cosmic and create a new empty Project.
Go to Project > Extensions and install the Cosmic Blocks extension. Find the ecommerce Block.
Follow the steps to install the Block content which includes content model and demo content.
Then run the command to install the ecommerce components in your codebase.
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:
// 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:
// 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:
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. First, install the Stripe clients with the following command:
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.
// .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).
// 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
.
// 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:
// 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. 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.
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.
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).
5. Deploy to your website hosting provider
Next, we'll deploy our ecommerce website to Vercel (which is a great choice to host your Next.js website). Other hosting options include Netlify and Render.
First, create a new git repository in GitHub and follow the steps to push your Next.js ecommerce website code.
After you have pushed your code to the repository, go to the Vercel dashboard and add a new project 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.
Now deploy your code. ๐
You should now see a production build of your ecommerce website ready to take payments for your products and services. ๐ฐ
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 to help you build optimized web experiences faster.
If you have any questions, reach out to me on X (fka Twitter) or on the Cosmic Discord server.