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
Design the course database schema
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.
Build the course catalog and enrollment flow
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.
Create the lesson viewing interface
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.
Implement progress tracking and quizzes
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.
Add a discussion forum per course
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.
Generate certificates on course completion
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
1E-LEARNING PLATFORM ARCHITECTURE2==================================34DATA TYPES:5 Course:6 - title, description, instructor (User)7 - thumbnail (image), category, price8 - is_published (yes/no)910 Module:11 - course (Course), title, order_index (number)1213 Lesson:14 - module (Module), title, order_index (number)15 - video_url (text), content (text)16 - duration_minutes (number)1718 Quiz:19 - lesson (Lesson), question (text)20 - options (list of texts)21 - correct_answer_index (number)2223 Enrollment:24 - student (User), course (Course)25 - enrolled_date, completed_date26 - progress_percent (number)2728 LessonProgress:29 - enrollment (Enrollment), lesson (Lesson)30 - completed (yes/no), completed_date31 - quiz_score (number)3233 Discussion:34 - course (Course), author (User)35 - message (text)36 - parent_discussion (Discussion)3738 Certificate:39 - enrollment (Enrollment)40 - certificate_number (text)41 - issued_date (date)4243KEY WORKFLOWS:44 Enroll in Course:45 → Create Enrollment (progress: 0%)46 → Navigate to first lesson4748 Mark Lesson Complete:49 → Create/update LessonProgress (completed: yes)50 → Calculate: completed lessons / total lessons * 10051 → Update Enrollment progress_percent52 → If 100%: trigger certificate generation5354 Quiz Submission:55 → Compare selected answer to correct_answer_index56 → Store quiz_score on LessonProgress57 → Only allow completion if score >= 80%5859 Generate Certificate:60 → Create Certificate record61 → Set Enrollment completed_date62 → Send congratulations email6364PAGES:65 courses — catalog with search/filter66 course-detail — overview, modules, enrollment67 lesson — video player, content, quiz, nav68 certificate — printable/downloadable certificate69 dashboard — enrolled courses, progress barsCommon 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.
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.
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.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation