Creating a Full Stack Udemy Clone Project with Next.js
In this article, we will walk through building a full-stack Udemy clone application with Next.js for the front end, MongoDB for the database, and Node.js/Express for the API. By the end, we will have a working course marketplace with user authentication, shopping cart functionality, course purchases, and deployment.
What is Udemy Marketplace?
Udemy is one of the largest online learning marketplaces in the world, with over 50 million students taking courses on a wide range of subjects from business to programming to personal development.
On Udemy, individual instructors can create and sell online video courses covering their areas of expertise. Courses typically include pre-recorded video lectures, slides, code examples, assignments, and quizzes.
Why build a full stack clone with Next.js?
There are a few key reasons it makes sense to build a Udemy clone project as a full-stack application using Next.js:
Next.js simplifies building server-rendered React apps, which is important for SEO and performance on a site like this with dynamic course data.
Having both the front end and backend developed together in a single codebase allows for tighter integration between the two and streamlines the development process.
Next.js generates HTML at build time so the frontend loading experience is very fast. This provides a smooth user experience when browsing courses.
Next.js routing and API integration makes it easy to fetch course data server-side when pages are rendered. This reduces the need for separate frontend/backend projects.
Next.js simplicity supports rapid iteration and deployment. New features can be deployed easily without making major changes to the underlying architecture.
Building the full-stack ourselves gives full control over the application and makes it easy to extend with things like payments, user accounts, etc. versus relying on other platforms.
Project Setup
The first step is to decide on our tech stack. For this project, we will use:
Next.js for the frontend - Next.js is a React framework that makes building full-stack applications easy with features like server-side rendering and automatic code splitting.
MongoDB as our database - MongoDB is a popular document-oriented NoSQL database that will allow us to store courses, users, orders, and other data in flexible document structures.
Node.js and Express for the API backend - We'll build a REST API with Express to handle data requests from the frontend like fetching courses, authentication, purchases, etc.
With our stack selected, let's set up the basic project structure:
udemy-clone/
frontend/
pages/
components/
styles/
api/
backend/
models/
routes/
server.js
db/
Inside the frontend
directory, run npx create-next-app
to initialize a new Next.js project. Then in backend
, run npm init
to create a new Node project.
Next, we'll need to design some basic data models for MongoDB to store our data. Here are examples of models we might need:
Course {
title: String,
description: String,
lessons: [Lesson],
price: Number,
//etc
}
Lesson {
title: String,
content: String
}
User {
name: String,
email: String,
password: String,
cart: [CartItem],
purchased: [Course]
}
CartItem {
course: ObjectId,
quantity: Number
}
Order {
user: ObjectId,
items: [CartItem],
purchaseDate: Date
}
Now our project is set up with the basic structure and data models we need!
Frontend Development
Let's start building out the frontend pages. We'll begin with a Landing page to display featured courses:
// pages/index.js
export default function Home() {
const [courses, setCourses] = useState([])
useEffect(() => {
// fetch featured courses from API
fetchCourses()
}, [])
async function fetchCourses() {
const res = await fetch('/api/courses')
setCourses(res.data)
}
return (
<Layout>
<Hero />
<CoursesList courses={courses} />
<Footer />
</Layout>
)
}
Some key components we include:
Layout wrapper for consistent page structure
Hero banner section
CoursesList to display courses fetched from API
Footer shared footer
Now let's build out the Course Detail page to view a specific course:
// pages/courses/[slug].js
export default function Course({course}) {
return (
<Layout>
<Breadcrumbs category={course.category} />
<CourseHero
image={course.image}
title={course.title}
/>
<CourseDetails course={course}>
<AddCartButton course={course} />
<LessonsList lessons={course.lessons}/>
<Footer />
</Layout>
)
}
export async function getServerSideProps({params}) {
const res = await fetch(`/api/courses/${params.slug}`)
const course = await res.json()
return {
props: {
course
}
}
}
And we render the course content passed via SSR.
Next we'll build the Cart, Checkout, and User dashboard pages. Some key pieces:
Display cart items and totals
Collect payment information at checkout
Save orders to the database
Connect to Stripe for payments
Show user profile/purchases
With our core pages created, the front end is taking shape! Now it's time to connect it to our backend API.
Backend Development
First, install dependencies:
npm install express mongodb cors body-parser
In server.js
:
const express = require('express');
const mongoose = require('mongodb');
const cors = require('cors');
const app = express();
app.use(cors());
app.use(express.json());
// Connect to MongoDB
mongoose.connect(MONGO_URL)
Then we'll create some sample routes:
// Get all courses
app.get('/api/courses', async (req, res) => {
const courses = await Course.find()
res.send(courses)
})
// Get single course
app.get('/api/courses/:id', async (req, res) => {
const course = await Course.findById(req.params.id)
res.send(course)
})
// Add course to cart
app.post('/api/cart', async (req, res) => {
// Save to database
res.send({message: 'Added to cart!'})
})
Continue building out CRUD routes for courses, users, orders etc. We also need authentication routes:
// Register user
app.post('/api/users/register', async (req, res) => {
// Validate & save user
const token = createJWT(user)
res.send({token})
})
// Login user
app.post('/api/users/login', async (req, res) => {
// Validate credentials
const token = createJWT(user)
res.send({token})
})
Our API is ready! Deploy it to Heroku so our frontend can consume it.
Purchasing Integration
Now for one of the most important parts - payments! Let's integrate with Stripe to enable credit card purchases.
First, sign up for a Stripe account and get your publishable and secret keys. Then:
// server.js
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY)
app.post('/api/checkout', async (req, res) => {
const session = await stripe.checkout.sessions.create({
// Create checkout session
})
res.json({
sessionId: session.id
})
})
On the frontend Checkout page:
// checkout.js
const stripe = Stripe(process.env.STRIPE_PUBLISHABLE_KEY)
async function handleSubmit() {
// Call backend to create Checkout Session
const { session } = await fetch('/api/checkout')
// Redirect to Checkout
const { error } = await stripe.redirectToCheckout({
// Checkout props
})
if (error) {
console.warn(error)
}
}
This will open the Stripe checkout modal. On successful payment, the Order can be saved to the database and access to courses granted.
And with that, purchases are integrated!
Deployment
Finally, let's deploy our fullstack app so it's live on the web!
We've already deployed the API to Heroku. For the frontend:
Build the Next.js production build:
npm run build
Install and initialize Vercel:
npm install -g vercel vercel
Link the github repository and deploy
Vercel will detect the build outputs and deploy the production site. Now users can visit your site and browse, purchase and learn from courses!
Final Thoughts
This article guides through building a full stack Udemy clone using Next.js, MongoDB, Node/Express featuring course catalogs, payments with Stripe, user auth, and deployment to Vercel and Heroku for hands-on full stack dev experience.
Subscribe to my newsletter
Read articles from prasad venkatachalam directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
prasad venkatachalam
prasad venkatachalam
With over 10 years in web and app development, I'm more interested in writing about clone solutions of popular brands