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
Design the quiz Data Types
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.
Build the quiz-taking interface
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.
Record answers and implement scoring
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.
Add a countdown timer for timed quizzes
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.
Build the results and analytics dashboard
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
1QUIZ PLATFORM SUMMARY2======================34DATA TYPES:5 Quiz: title, description, time_limit (min), passing_score, active6 Question: quiz (Quiz), question_text, question_type, order, points7 AnswerChoice: question (Question), choice_text, is_correct8 QuizAttempt: quiz, user, score, total_possible, percentage, completed_date9 UserAnswer: attempt, question, selected_answer, is_correct1011PAGES:12 quiz-list: Browse available quizzes13 take-quiz (type: Quiz): Take a quiz one question at a time14 quiz-results (type: QuizAttempt): View results and breakdown15 quiz-history: View all past attempts1617CUSTOM STATES (take-quiz page):18 - QuestionIndex (number, default: 1)19 - CurrentAttempt (QuizAttempt)20 - TimerRunning (yes/no, default: yes)2122KEY WORKFLOWS:23 Start Quiz:24 → Create QuizAttempt (quiz, user, score=0)25 → Set state CurrentAttempt = Result26 → Set QuestionIndex = 12728 Select Answer:29 → Create UserAnswer (attempt, question, selected_answer, is_correct)30 → Or Make Changes if answer already exists for this question3132 Next Question: Set QuestionIndex = QuestionIndex + 133 Previous: Set QuestionIndex = QuestionIndex - 13435 Submit Quiz:36 → Count correct UserAnswers for CurrentAttempt37 → Calculate percentage: (correct / total) * 10038 → Make Changes to CurrentAttempt: score, percentage, completed_date39 → Go to quiz-results page with CurrentAttempt4041 Timer Expired (Do when condition is true):42 → When time_remaining <= 0 AND TimerRunning is yes43 → Set TimerRunning = no44 → Trigger Submit Quiz workflowCommon 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.
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?
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.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation