MedusaJS is a powerful open-source e-commerce backend that provides flexibility for modern storefronts, while Builder.io is a visual CMS that enables no-code page creation and A/B testing. By integrating these two tools, you can build a dynamic, customizable storefront with the power of Medusa’s backend and Builder.io’s visual editing capabilities.
In this guide, I’ll walk you through how to integrate Builder.io with MedusaJS to create custom e-commerce pages seamlessly.
Prerequisites
Before getting started, ensure you have the following installed:
Node.js v20+
Git CLI
PostgreSQL (Required for Medusa’s database)
Builder.io React SDK
Step 1: Set Up MedusaJS
If you don’t already have a Medusa application installed, run the following command to install both the Medusa backend and the Next.js storefront starter:
npx create-medusa-app@latest --with-nextjs-starter
During setup, you’ll be prompted to enter a project name. Once the installation completes:
- The Medusa backend will be in the
{project-name}
directory. - The Next.js storefront will be in
{project-name}-storefront
.
After installation, you can access:
Medusa Admin Dashboard:
http://localhost:9000/app
Next.js Storefront:
http://localhost:8000
For additional setup details, refer to the Medusa installation guide.
Step 2: Install Builder.io in Your Next.js Storefront
Assuming you are using Next.js for the storefront, install the required Builder.io packages:
npm install @builder.io/react @builder.io/sdk
For additional details, check out Builder.io’s Next.js integration guide.
Step 3: Add a Builder Component
Create a new file at:
/src/modules/common/components/builder/index.tsx
(Create the directory if it doesn’t exist).
Paste the following code inside:
"use client";
import { ComponentProps } from "react";
import { BuilderComponent, useIsPreviewing } from "@builder.io/react";
import { builder } from "@builder.io/sdk";
import DefaultErrorPage from "next/error";
type BuilderPageProps = ComponentProps<typeof BuilderComponent>;
// Replace with your Builder.io Public API Key
builder.init("Your-Builder-Public-API-Key");
export function RenderBuilderContent(props: BuilderPageProps) {
const isPreviewing = useIsPreviewing();
return props.content || isPreviewing ? (
<BuilderComponent {...props} />
) : (
<DefaultErrorPage statusCode={404} />
);
}
Step 4: Enable Dynamic Pages with Builder.io
Add Builder Page Support
Create a file at:
/src/app/[countryCode]/(main)/[...page]/page.tsx
Paste the following code inside:
import { Metadata } from "next";
import { builder } from "@builder.io/sdk";
import { RenderBuilderContent } from "@modules/common/components/builder";
// Initialize Builder.io
builder.init("Your-Builder-Public-API-Key");
export const metadata: Metadata = {
title: "Builder.io + Medusa Next.js Starter Template",
description: "A performant e-commerce starter template with Next.js 14 and Medusa.",
};
interface BuilderPageProps {
params: {
page?: string[];
countryCode: string;
};
}
export default async function BuilderPage({ params }: BuilderPageProps) {
const { countryCode, page = [] } = params;
const urlPath = `/${countryCode}/${page.join("/")}`.replace(/\/$/, "");
const content = await builder
.get("page", {
userAttributes: { urlPath },
options: { countryCode },
locale: countryCode,
prerender: false,
})
.toPromise();
return <RenderBuilderContent content={content} model="page" locale={countryCode} />;
}
Set Up Builder for the Home Page
If you want your home page (e.g., http://localhost:8000/dk
) to be editable via Builder, modify:
/src/app/[countryCode]/(main)/page.tsx
Paste the following:
import { Metadata } from "next";
import { builder } from "@builder.io/sdk";
import { RenderBuilderContent } from "@modules/common/components/builder";
import FeaturedProducts from "@modules/home/components/featured-products";
import { listCollections } from "@lib/data/collections";
import { getRegion } from "@lib/data/regions";
// Initialize Builder.io
builder.init("Your-Builder-Public-API-Key");
export const metadata: Metadata = {
title: "Builder.io + Medusa Next.js Starter Template",
description: "A performant e-commerce starter template with Next.js 14 and Medusa.",
};
interface HomeProps {
params: {
countryCode: string;
};
}
export default async function Home({ params }: HomeProps) {
const { countryCode } = params;
const region = await getRegion(countryCode);
const { collections } = await listCollections({ fields: "id, handle, title" });
if (!collections || !region) {
return null;
}
const content = await builder
.get("page", {
userAttributes: { urlPath: "/" },
options: { countryCode },
locale: countryCode,
prerender: false,
})
.toPromise();
return (
<>
<RenderBuilderContent content={content} model="page" locale={countryCode} />
<div className="py-12">
<ul className="flex flex-col gap-x-6">
<FeaturedProducts collections={collections} region={region} />
</ul>
</div>
</>
);
}
Step 5: Configure Builder.io Preview
To enable Builder.io’s Visual Editor, follow these steps:
- Go to Builder.io Models and select the Page model.
- Set the Preview URL to
http://localhost:<your-port>
(replace<your-port>
with your app’s port). - Click Save.
This allows Builder.io to preview and edit your Next.js pages in real-time.
Conclusion
By integrating MedusaJS with Builder.io, you now have a flexible e-commerce storefront with powerful backend capabilities and no-code page editing. You can now:
Manage products and orders via Medusa.
Customize page layouts with Builder.io’s drag-and-drop editor.
Implement dynamic content updates without touching code.
If you have any questions or run into issues, drop them in the comments!