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

How to build a quiz platform in Bubble

Building a quiz platform in Bubble involves creating Data Types for quizzes, questions, answer choices, and user attempts. This tutorial walks you through the full architecture: a quiz builder for admins, a quiz-taking interface with timed questions, automatic scoring, and a results dashboard with analytics.

What you'll learn

  • How to design a data structure for quizzes with multiple question types
  • How to build a quiz-taking interface with custom states for navigation
  • How to implement automatic scoring and results calculation
  • How to create a results dashboard with score history
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner6 min read30-40 minAll Bubble plansMarch 2026RapidDev Engineering Team
TL;DR

Building a quiz platform in Bubble involves creating Data Types for quizzes, questions, answer choices, and user attempts. This tutorial walks you through the full architecture: a quiz builder for admins, a quiz-taking interface with timed questions, automatic scoring, and a results dashboard with analytics.

Overview: Building a Quiz Platform in Bubble

Quizzes are used in education, hiring, marketing, and entertainment. This tutorial shows you how to build a complete quiz engine in Bubble with a question bank, multiple choice answers, timed rounds, automatic scoring, and a results page. The architecture supports multiple quizzes with different question sets.

Prerequisites

  • A Bubble app with user registration and login
  • Basic familiarity with Data Types, Repeating Groups, and custom states
  • Understanding of Bubble workflows and conditions

Step-by-step guide

1

Design the quiz Data Types

Create these Data Types in the Data tab. Quiz: title (text), description (text), time_limit (number, in minutes), passing_score (number), active (yes/no). Question: quiz (Quiz), question_text (text), question_type (Option Set: Multiple Choice, True/False), order (number), points (number). AnswerChoice: question (Question), choice_text (text), is_correct (yes/no). QuizAttempt: quiz (Quiz), user (User), score (number), total_possible (number), percentage (number), completed_date (date). UserAnswer: attempt (QuizAttempt), question (Question), selected_answer (AnswerChoice), is_correct (yes/no).

Expected result: A complete data structure supporting quizzes, questions, answers, and user attempts.

2

Build the quiz-taking interface

Create a page called take-quiz with page type Quiz. Add a Group to display one question at a time. Inside, add a Text element for the question text (Current Page Quiz's Questions:item #QuestionIndex's question_text where QuestionIndex is a custom state). Below, add a Repeating Group of AnswerChoices for the current question. Each cell shows the choice text with a radio-button-style selection using conditionals. Add Previous and Next buttons that increment or decrement the QuestionIndex custom state.

Pro tip: Use a custom state called QuestionIndex (type: number, default: 1) to track which question the user is currently viewing.

Expected result: Users see one question at a time with answer choices and can navigate between questions.

3

Record answers and implement scoring

When the user selects an answer, create a UserAnswer record with the attempt, question, selected answer, and whether it is correct (selected_answer's is_correct). When the user clicks Submit Quiz, calculate the score: count UserAnswers where attempt = current attempt AND is_correct = yes, multiply by points per question. Save the score and percentage to the QuizAttempt record. Navigate to a results page.

Expected result: User answers are recorded and the quiz is scored automatically upon submission.

4

Add a countdown timer for timed quizzes

If the Quiz has a time_limit, add a timer using the same pattern from the countdown timer tutorial. Set the target time to Current Page Quiz's time_limit minutes from when the page loads. Display minutes and seconds remaining. When the timer reaches zero, automatically submit the quiz using a Do When Condition Is True event that triggers the submit workflow.

Expected result: Timed quizzes auto-submit when time runs out, with a visible countdown.

5

Build the results and analytics dashboard

Create a results page showing the user's score, percentage, pass/fail status, and a breakdown of each question with the correct and selected answers. Add a Repeating Group of UserAnswers for the current attempt, showing which were right and wrong. For analytics, add a history section with a Repeating Group of QuizAttempts for the current user, sorted by date descending.

Expected result: Users see detailed results after each quiz and can view their score history.

Complete working example

Workflow summary
1QUIZ PLATFORM SUMMARY
2======================
3
4DATA TYPES:
5 Quiz: title, description, time_limit (min), passing_score, active
6 Question: quiz (Quiz), question_text, question_type, order, points
7 AnswerChoice: question (Question), choice_text, is_correct
8 QuizAttempt: quiz, user, score, total_possible, percentage, completed_date
9 UserAnswer: attempt, question, selected_answer, is_correct
10
11PAGES:
12 quiz-list: Browse available quizzes
13 take-quiz (type: Quiz): Take a quiz one question at a time
14 quiz-results (type: QuizAttempt): View results and breakdown
15 quiz-history: View all past attempts
16
17CUSTOM STATES (take-quiz page):
18 - QuestionIndex (number, default: 1)
19 - CurrentAttempt (QuizAttempt)
20 - TimerRunning (yes/no, default: yes)
21
22KEY WORKFLOWS:
23 Start Quiz:
24 Create QuizAttempt (quiz, user, score=0)
25 Set state CurrentAttempt = Result
26 Set QuestionIndex = 1
27
28 Select Answer:
29 Create UserAnswer (attempt, question, selected_answer, is_correct)
30 Or Make Changes if answer already exists for this question
31
32 Next Question: Set QuestionIndex = QuestionIndex + 1
33 Previous: Set QuestionIndex = QuestionIndex - 1
34
35 Submit Quiz:
36 Count correct UserAnswers for CurrentAttempt
37 Calculate percentage: (correct / total) * 100
38 Make Changes to CurrentAttempt: score, percentage, completed_date
39 Go to quiz-results page with CurrentAttempt
40
41 Timer Expired (Do when condition is true):
42 When time_remaining <= 0 AND TimerRunning is yes
43 Set TimerRunning = no
44 Trigger Submit Quiz workflow

Common mistakes when building a quiz platform in Bubble

Why it's a problem: Loading all questions in a Repeating Group instead of showing one at a time

How to avoid: Use a custom state (QuestionIndex) to display one question at a time, navigating with Next and Previous buttons

Why it's a problem: Not checking if an answer already exists before creating a new one

How to avoid: Before creating a UserAnswer, search for an existing one with the same attempt and question. If found, use Make Changes instead of Create.

Why it's a problem: Calculating scores client-side without validation

How to avoid: Calculate the final score in a backend workflow using server-side data for integrity

Best practices

  • Show one question at a time using a custom state index for better UX and timer fairness
  • Check for existing answers before creating new ones to handle answer changes
  • Calculate final scores server-side for integrity
  • Store the is_correct flag at answer time so scoring does not depend on future changes to the answer key
  • Add a progress indicator showing question X of Y
  • Randomize question order using :random sorting to prevent cheating across attempts

Still stuck?

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

ChatGPT Prompt

I want to build a quiz platform in Bubble.io with multiple choice questions, timed quizzes, automatic scoring, and a results dashboard. Can you outline the Data Types, page structure, and key workflows?

Bubble Prompt

Build a quiz system for my app. I need a Quiz data type with Questions and AnswerChoices, a quiz-taking page that shows one question at a time, automatic scoring, and a results page showing right and wrong answers.

Frequently asked questions

Can I add different question types like fill-in-the-blank?

Yes. Add a question_type field to the Question Data Type. Use conditions to show different input elements (text input for fill-in, radio buttons for multiple choice) based on the question type.

How do I prevent users from retaking the same quiz?

Search for QuizAttempts where quiz = current quiz AND user = Current User. If a result exists, show a message instead of the start button, or allow retakes but track all attempts.

Can I randomize question order?

Yes. When loading questions, use the :random sorting option on your search to present questions in a different order each time.

How do I share quiz results?

Create a shareable results page that accepts a QuizAttempt as page data. Generate a link that includes the attempt's Unique ID. Anyone with the link can view the results.

Can I add images to questions?

Yes. Add an image field to the Question Data Type. Display it in an Image element on the quiz-taking page with a condition to only show when the image is not empty.

Is this suitable for a large-scale assessment platform?

For basic quizzes, yes. For enterprise assessments with proctoring, complex scoring rubrics, or thousands of concurrent users, you may need additional optimization. RapidDev can help build scalable assessment platforms in Bubble.

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.