Skip to main content
RapidDev - Software Development Agency
bubble-tutorial

How to build an eLearning platform in Bubble.io: Step-by-Step Guide

Building an e-learning platform in Bubble involves creating courses with video lessons, inline quizzes, completion tracking, discussion forums, and certificate generation. This tutorial covers the database schema for courses, modules, and lessons, the student-facing learning interface, progress tracking workflows, quiz grading logic, and automated certificate creation on course completion.

What you'll learn

  • How to design a course and lesson database structure in Bubble
  • How to build a student-facing learning interface with video lessons
  • How to implement progress tracking and inline quizzes
  • How to generate certificates on course completion
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner8 min read35-45 minAll Bubble plans (Growth plan+ recommended for video hosting and backend workflows)March 2026RapidDev Engineering Team
TL;DR

Building an e-learning platform in Bubble involves creating courses with video lessons, inline quizzes, completion tracking, discussion forums, and certificate generation. This tutorial covers the database schema for courses, modules, and lessons, the student-facing learning interface, progress tracking workflows, quiz grading logic, and automated certificate creation on course completion.

Overview: Building an E-Learning Platform in Bubble

This tutorial walks you through building a student-facing e-learning platform in Bubble. You will create a structured course system with modules and lessons, embed video content, track student progress, add quizzes for knowledge checks, implement discussion forums per course, and generate completion certificates — all without writing code.

Prerequisites

  • A Bubble app with user authentication configured
  • A video hosting account (Vimeo, YouTube, or Wistia) for lesson videos
  • Familiarity with Bubble Data Types, Repeating Groups, and workflows
  • Basic understanding of Bubble custom states

Step-by-step guide

1

Design the course database schema

In the Data tab, create these Data Types: (1) Course — fields: title (text), description (text), instructor (User), thumbnail (image), category (Option Set: CourseCategory), is_published (yes/no), price (number). (2) Module — fields: course (Course), title (text), order_index (number), description (text). (3) Lesson — fields: module (Module), title (text), order_index (number), video_url (text), content (text), duration_minutes (number). (4) Quiz — fields: lesson (Lesson), question (text), options (list of texts), correct_answer_index (number). (5) Enrollment — fields: student (User), course (Course), enrolled_date (date), completed_date (date), progress_percent (number). (6) LessonProgress — fields: enrollment (Enrollment), lesson (Lesson), completed (yes/no), completed_date (date), quiz_score (number). (7) Discussion — fields: course (Course), author (User), message (text), parent_discussion (Discussion).

Expected result: Your database supports a complete course structure with modules, lessons, quizzes, enrollment tracking, and discussions.

2

Build the course catalog and enrollment flow

Create a 'courses' page with a Repeating Group showing published courses (Do a Search for Courses where is_published = yes). Display thumbnail, title, instructor name, category, and price. Link each cell to a 'course-detail' page (type = Course). On the detail page, show the course description, module list (Repeating Group of Modules where course = Current Page Course, sorted by order_index), and an Enroll button. The Enroll workflow: (1) Create an Enrollment with student = Current User, course = Current Page Course, progress_percent = 0. (2) Navigate to the first lesson of the first module.

Expected result: Students can browse the course catalog, view course details with module outlines, and enroll to start learning.

3

Create the lesson viewing interface

Create a 'lesson' page (type = Lesson). At the top, embed the video using an HTML element with an iframe pointing to the lesson's video_url. Below the video, display the lesson content text. On the left sidebar, show the course module structure with a nested Repeating Group: outer RG for Modules, inner RG for Lessons within each module. Highlight the current lesson. Add checkmarks next to completed lessons by checking if a LessonProgress exists where enrollment's student = Current User and lesson = Current Cell's Lesson and completed = yes. Add Previous and Next buttons that navigate to the adjacent lesson based on order_index.

Pro tip: Use a custom state on the page to track the current enrollment — fetch it once on page load with Do a Search for Enrollments where student = Current User and course = Current Lesson's Module's Course, and store it in the state for fast access throughout the page.

Expected result: Students see the lesson video, content text, and course navigation sidebar with progress indicators.

4

Implement progress tracking and quizzes

Add a Mark as Complete button below the lesson content. The workflow: (1) Create a LessonProgress with completed = yes if one does not already exist, or update the existing one. (2) Calculate new progress_percent on the Enrollment: count of completed LessonProgress records divided by total lessons in the course, multiplied by 100. (3) Update the Enrollment's progress_percent field. For quizzes, when a lesson has associated Quiz records, display them after the video. Show the question, answer options as clickable buttons, and check the selected answer against correct_answer_index. Store the quiz_score on the LessonProgress. Only allow Mark as Complete if the quiz score meets a minimum threshold (e.g., 80%).

Expected result: Students can mark lessons complete, take quizzes, and see their overall course progress percentage updated in real time.

5

Add a discussion forum per course

On the course detail page, add a Discussion tab. Display a Repeating Group of Discussions where course = Current Page Course and parent_discussion is empty (top-level posts), sorted by Created Date descending. Inside each cell, show the author, message, date, and a Reply button. Replies are loaded in a nested Repeating Group where parent_discussion = Current Cell's Discussion. The Reply button shows a text area and Submit button that creates a new Discussion with parent_discussion set to the current post. Add a New Discussion form at the top for starting new threads.

Expected result: Students and instructors can start discussion threads and reply to posts within each course.

6

Generate certificates on course completion

When an Enrollment's progress_percent reaches 100, trigger a workflow to generate a certificate. Create a Certificate Data Type with fields: enrollment (Enrollment), certificate_number (text, auto-generated), issued_date (date). The workflow creates the Certificate record and updates the Enrollment's completed_date. For the visual certificate, create a 'certificate' page showing the student name, course title, completion date, and certificate number in a designed layout. Use Bubble's built-in ability to convert a page to PDF or use a plugin like PDF Conjurer to generate a downloadable certificate. Add a View Certificate button on the student dashboard.

Expected result: Students automatically receive a certificate when they complete all lessons, viewable and downloadable from their dashboard.

Complete working example

Workflow summary
1E-LEARNING PLATFORM ARCHITECTURE
2==================================
3
4DATA TYPES:
5 Course:
6 - title, description, instructor (User)
7 - thumbnail (image), category, price
8 - is_published (yes/no)
9
10 Module:
11 - course (Course), title, order_index (number)
12
13 Lesson:
14 - module (Module), title, order_index (number)
15 - video_url (text), content (text)
16 - duration_minutes (number)
17
18 Quiz:
19 - lesson (Lesson), question (text)
20 - options (list of texts)
21 - correct_answer_index (number)
22
23 Enrollment:
24 - student (User), course (Course)
25 - enrolled_date, completed_date
26 - progress_percent (number)
27
28 LessonProgress:
29 - enrollment (Enrollment), lesson (Lesson)
30 - completed (yes/no), completed_date
31 - quiz_score (number)
32
33 Discussion:
34 - course (Course), author (User)
35 - message (text)
36 - parent_discussion (Discussion)
37
38 Certificate:
39 - enrollment (Enrollment)
40 - certificate_number (text)
41 - issued_date (date)
42
43KEY WORKFLOWS:
44 Enroll in Course:
45 Create Enrollment (progress: 0%)
46 Navigate to first lesson
47
48 Mark Lesson Complete:
49 Create/update LessonProgress (completed: yes)
50 Calculate: completed lessons / total lessons * 100
51 Update Enrollment progress_percent
52 If 100%: trigger certificate generation
53
54 Quiz Submission:
55 Compare selected answer to correct_answer_index
56 Store quiz_score on LessonProgress
57 Only allow completion if score >= 80%
58
59 Generate Certificate:
60 Create Certificate record
61 Set Enrollment completed_date
62 Send congratulations email
63
64PAGES:
65 courses catalog with search/filter
66 course-detail overview, modules, enrollment
67 lesson video player, content, quiz, nav
68 certificate printable/downloadable certificate
69 dashboard enrolled courses, progress bars

Common mistakes when building an eLearning platform in Bubble.io: Step-by-Step Guide

Why it's a problem: Hosting videos directly in Bubble's file storage

How to avoid: Host videos on Vimeo, YouTube (unlisted), or Wistia and embed them using iframe URLs in your Bubble HTML element

Why it's a problem: Calculating progress with a search on every page load

How to avoid: Store progress_percent as a field on Enrollment and update it only when a lesson is marked complete

Why it's a problem: Not enforcing lesson order or prerequisites

How to avoid: Add an Only when condition on the Mark Complete button that checks if all previous lessons in the module are completed

Best practices

  • Host videos on a dedicated platform like Vimeo or Wistia for adaptive streaming quality
  • Store progress_percent on the Enrollment record to avoid recalculating on every page load
  • Use order_index fields on Modules and Lessons to control display and navigation order
  • Cache the current Enrollment in a custom state on page load for fast reference throughout the lesson page
  • Require quiz completion with a minimum score before marking lessons complete
  • Paginate discussion threads to avoid loading hundreds of posts at once
  • Use backend workflows for certificate generation to ensure they complete reliably

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I want to build an e-learning platform in Bubble.io with courses, video lessons, quizzes, progress tracking, and certificate generation. Help me design the database schema and key student-facing workflows.

Bubble Prompt

Create a lesson page that embeds a video from a URL, shows lesson content below it, displays a sidebar with all course modules and lessons with completion checkmarks, and has a Mark Complete button that updates the student's progress percentage.

Frequently asked questions

What is the best way to embed videos in Bubble?

Host videos on Vimeo (Pro for privacy controls), YouTube (unlisted), or Wistia. Embed them using an HTML element with an iframe tag pointing to the video's embed URL. This gives you adaptive streaming without consuming Bubble storage.

Can I charge for courses in Bubble?

Yes. Use the Stripe plugin to charge students at enrollment. Store the payment status on the Enrollment record and only grant access to course content when payment is confirmed.

How do I generate downloadable certificates?

Create a certificate page with the student name, course title, and date laid out attractively. Use a plugin like PDF Conjurer to convert the page to a downloadable PDF, or let students print the page directly from their browser.

Can I track how long students spend on each lesson?

Yes. Record the timestamp when a student opens a lesson page and when they leave or mark complete. Store the difference as time_spent on the LessonProgress record. Use the Do when condition is true event to detect page unload.

Can RapidDev help build an e-learning platform in Bubble?

Yes. RapidDev can build a complete e-learning platform including course management, video integration, quiz engines, progress tracking, certificate generation, and payment processing — tailored to your educational content and audience.

How do I handle different content types beyond video?

Add a content_type field to Lessons (Option Set: Video, Text, PDF, Interactive). Use conditional visibility to show the appropriate viewer element based on content_type — an HTML iframe for videos, a Text element for text content, or a file download link for PDFs.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.