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

How to add voting and polling features in Bubble.io: Step-by-Step Guide

Build a voting and polling system in Bubble by creating a Poll data type with related Options, enforcing one-vote-per-user with a Votes data type, tallying results in real time, and displaying them as bar charts. This tutorial covers poll creation, vote recording, duplicate prevention, and live result visualization.

What you'll learn

  • How to design the data model for polls, options, and votes
  • How to enforce one-vote-per-user using database constraints
  • How to display live vote tallies and percentages
  • How to show results as bar charts after voting
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner6 min read20-25 minAll Bubble plansMarch 2026RapidDev Engineering Team
TL;DR

Build a voting and polling system in Bubble by creating a Poll data type with related Options, enforcing one-vote-per-user with a Votes data type, tallying results in real time, and displaying them as bar charts. This tutorial covers poll creation, vote recording, duplicate prevention, and live result visualization.

Overview: Voting and Polling in Bubble

Polls and voting features let your users weigh in on questions, rank options, and see community sentiment. This tutorial builds a complete polling system in Bubble with multiple-choice options, one-vote-per-user enforcement, real-time result counting, and visual result display. It is ideal for community apps, feedback systems, and decision-making platforms.

Prerequisites

  • A Bubble account with user authentication set up
  • Basic understanding of Data Types, Workflows, and Repeating Groups
  • Familiarity with conditional formatting

Step-by-step guide

1

Create the Poll, Option, and Vote data types

Go to Data tab and create three Data Types. 'Poll': question (text), created_by (User), is_active (yes/no, default yes), end_date (date). 'PollOption': poll (Poll), option_text (text), vote_count (number, default 0). 'Vote': poll (Poll), option (PollOption), voter (User). The Vote type links a user to their chosen option, enabling duplicate prevention.

Pro tip: Storing vote_count directly on PollOption avoids counting searches later and gives instant results.

Expected result: Three Data Types are created with the specified fields and relationships.

2

Build the poll creation form

Create a page or popup for creating polls. Add an Input for the poll question, a Repeating Group with Inputs for option text (start with 3-4 rows), and a Date picker for the end date. Add a 'Create Poll' button with this workflow: Create a new Poll → question = Input's value, created_by = Current User, end_date = Date picker's value. Then for each option input: Create a new PollOption → poll = Result of step 1, option_text = input value. Use the Repeating Group's List of Inputs to iterate.

Expected result: Users can create a poll with a question, multiple options, and an end date.

3

Display the poll and voting buttons

On your poll display page, show the poll question in a Text element. Add a Repeating Group with data source: Do a search for PollOption (constraint: poll = Current page's Poll). In each cell, display the option_text and a 'Vote' button. The Vote button should be conditionally disabled when: Do a search for Vote (constraint: poll = Current page's Poll, voter = Current User) :count > 0. This prevents double voting.

Expected result: The poll displays with clickable vote buttons that become disabled after the user has voted.

4

Record votes and update tallies

On the Vote button workflow: Action 1: Create a new Vote → poll = Current page's Poll, option = Current cell's PollOption, voter = Current User. Action 2: Make changes to Current cell's PollOption → vote_count = Current cell's PollOption's vote_count + 1. Add an 'Only when' condition on the workflow: Do a search for Vote (poll = Current page's Poll, voter = Current User) :count is 0. This is a server-side guard against duplicate votes.

Expected result: Clicking a vote button creates a Vote record and increments the option's vote_count by 1.

5

Show live results with progress bars

Below each option in the Repeating Group, add a Group styled as a progress bar. Set its width dynamically: Current cell's PollOption's vote_count / Current page's Poll's PollOptions:each item's vote_count:sum × 100 (as a percentage). Set the background color to your brand color. Next to it, display the vote count and percentage as text. Add a conditional to show results either always or only after the user has voted.

Pro tip: Use conditional visibility to hide results until the user votes — this prevents anchoring bias where users follow the leading option.

Expected result: After voting, users see a bar chart of results showing each option's percentage and count.

Complete working example

Workflow summary
1VOTING AND POLLING WORKFLOW SUMMARY
2======================================
3
4DATA TYPES:
5 Poll: question (text), created_by (User), is_active (yes/no),
6 end_date (date)
7 PollOption: poll (Poll), option_text (text), vote_count (number, default 0)
8 Vote: poll (Poll), option (PollOption), voter (User)
9
10WORKFLOW: Create Poll
11 Event: When "Create Poll" button is clicked
12 Action 1: Create Poll question, created_by, end_date
13 Action 2-N: Create PollOption for each option input
14 poll = Result of step 1, option_text = input value
15
16WORKFLOW: Cast Vote
17 Event: When "Vote" button is clicked
18 Condition: Search for Vote (poll + voter) :count is 0
19 Action 1: Create Vote poll, option = Current cell's PollOption, voter
20 Action 2: Make changes to Current cell's PollOption
21 vote_count = vote_count + 1
22
23DISPLAY:
24 Repeating Group: Search for PollOption (poll = current poll)
25 Each cell:
26 - option_text (text)
27 - Vote button (disabled when user already voted)
28 - Progress bar (width = vote_count / total_votes × 100%)
29 - Count + percentage text
30
31CONDITIONALS:
32 Vote button disabled: when Vote search (poll + voter) count > 0
33 Results visible: when Vote search (poll + voter) count > 0
34 Poll expired: when Current date/time > Poll's end_date
35 hide vote buttons, show results only

Common mistakes when adding voting and polling features in Bubble.io: Step-by-Step Guide

Why it's a problem: Only checking for duplicate votes on the frontend

How to avoid: Add an Only when condition on the vote workflow action itself that checks the Vote search count is 0, enforcing the rule server-side.

Why it's a problem: Counting votes with a search instead of storing vote_count on options

How to avoid: Store and increment vote_count directly on the PollOption record for instant, WU-efficient display

Why it's a problem: Not handling expired polls

How to avoid: Add an Only when condition: Current date/time < Current page's Poll's end_date on the vote workflow

Best practices

  • Store vote_count directly on PollOption records to avoid expensive count searches
  • Enforce one-vote-per-user both in UI (disabled button) and workflow (Only when condition)
  • Hide results until the user has voted to prevent anchoring bias
  • Add an end_date to polls and disable voting when expired
  • Use privacy rules on the Vote type to prevent users from seeing who voted for what
  • Add a total_votes field on Poll and update it with each vote for quick total display
  • Allow poll creators to close polls early by toggling is_active to no

Still stuck?

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

ChatGPT Prompt

I want to build a polling feature in my Bubble.io app where users can create polls with multiple options, vote once per poll, and see live results as bar charts. Can you design the data model and outline the key workflows?

Bubble Prompt

Add a voting and polling feature to my app. Create Poll, PollOption, and Vote data types. Build a poll creation form and a voting page with one-vote-per-user enforcement and live progress bar results.

Frequently asked questions

Can I allow anonymous voting without user accounts?

Not reliably. Without user accounts, you cannot enforce one-vote-per-person. You could use browser cookies or IP tracking, but these are easily circumvented. User authentication is recommended for fair voting.

How do I show results as a pie chart instead of bars?

Install the Chart.js plugin from the Plugins tab. Add a Pie chart element and set its data source to the PollOptions search. Map option_text to labels and vote_count to values.

Can users change their vote?

Yes, with additional logic. When a user clicks a new option: delete their existing Vote record, decrement the old option's vote_count, create a new Vote, and increment the new option's vote_count.

Will this work with thousands of voters?

Yes. Since vote_count is stored directly on PollOption, displaying results is a single search regardless of voter count. The individual Vote records exist for audit purposes but are not needed for display.

How do I embed a poll on another page?

Create the poll display as a Reusable Element. Give it a data source of type Poll. Place it on any page and set the data source to the specific poll you want to show.

Can RapidDev build a custom polling platform?

Yes. RapidDev can build advanced polling systems with features like ranked-choice voting, weighted polls, real-time WebSocket updates, and detailed analytics dashboards.

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.