What the Plugin Does
SurveyKiln adds two reusable elements to your Bubble app. No configuration, no external accounts, no code.
A full drag-and-drop survey editor. Users create questions, add conditional logic, and set the look and feel. The output is saved to your Bubble database.
Renders a completed survey as a fill-out form with validation, multi-page navigation, and a submit button. Responses are saved back to your database.
Your data never leaves your Bubble app. Survey definitions are stored as JSON in your database. Responses are stored as JSON in your database. SurveyKiln stores nothing.
27 Question Types
Installation
Installing SurveyKiln takes about 60 seconds.
Open the Plugins tab in your Bubble editor
Click Plugins in the left sidebar of your Bubble editor.
Search for SurveyKiln
Click Add plugins, search for SurveyKiln, click Install, then Done.
You're done — no API keys needed
SurveyKiln is fully client-side. No credentials, no external accounts. The SurveyKiln Builder and SurveyKiln Form elements now appear in your element picker.
Quick Start — 5 Minutes
The absolute minimum to get a working survey builder and a form in your app.
Part A — Let a user create a survey
Create a new page called survey-builder.
Drag the SurveyKiln Builder element onto the page. Set width to 100% and height to at least 800px.
Add a workflow in the Workflow tab:
Preview the page. Build a survey and click Save — it will be stored in your database.
Part B — Show the form to a respondent
Create a new page called take-survey. Set its Data type to Survey.
Drag the SurveyKiln Form element onto the page (at least 600px wide × 600px tall).
In the Form's Properties, set Survey JSON to: Current Page Survey's json_content
Add a workflow:
Done. Navigate to this page with a valid survey — the form renders automatically.
The Builder Element
Drag SurveyKiln Builder onto any page where your users should be able to create or edit surveys.
Minimum size: 900px wide × 700px tall. Set an explicit pixel height — "fit to content" will not work.
Properties
| Property | Type | Default | What it does |
|---|---|---|---|
| Survey JSON | Text | empty | Load an existing survey for editing. Pass the json_content field from your database. Leave empty to start a blank survey. |
| Show Save Button | Yes/No | Yes | Show or hide the Save button at the top of the builder. |
| Show Publish Button | Yes/No | Yes | Show or hide the Publish button at the top of the builder. |
| Primary Color | Color | #0066FF |
Accent color for buttons, active states, and interactive elements throughout the builder. |
| Logo URL v1.2.0 | Text | empty | Pass an image URL to replace the Survey Kiln logo in the builder header with your own. Recommended size: 160×32px. Leave empty to show the default logo. |
| App Name v1.2.0 | Text | Survey Builder |
Replace the "Survey Builder" header text with your own app name. The icon remains visible alongside the name. |
| Show Settings Tab v1.2.0 | Yes/No | Yes | Master toggle. Set to No to hide the entire Settings tab from your users. |
| Settings - Show Survey Info Section v1.2.0 | Yes/No | Yes | Show or hide the survey title and description fields in the Settings tab. |
| Settings - Show Schedule Section v1.2.0 | Yes/No | Yes | Show or hide the start date and close date scheduling fields in Settings. |
| Settings - Show Thank You Section v1.2.0 | Yes/No | Yes | Show or hide the thank you message and confetti toggle in Settings. |
| Settings - Show Redirect URL v1.2.0 | Yes/No | Yes | Show or hide the redirect URL field within the Thank You section. Only applies when Show Thank You Section is also enabled. |
| Settings - Show Styling Section v1.2.0 | Yes/No | Yes | Show or hide the background color, font size, and spacing controls in Settings. |
| Settings - Show Survey Options v1.2.0 | Yes/No | Yes | Show or hide the progress bar, back navigation, and PDF download toggles in Settings. |
Exposed States
States are data the element exposes to your Bubble app. Use them in conditions, text elements, or pass them to actions.
| State | Type | What it contains |
|---|---|---|
| survey_json | Text | The full survey definition as a JSON string. Updates with every change. Save this to your database. |
| is_dirty | Yes/No | yes when there are unsaved changes. Use this to show a "you have unsaved changes" warning. |
| question_count | Number | Total number of questions in the current survey. |
| page_count | Number | Total number of pages in the current survey. |
Events
| Event | When it fires |
|---|---|
| Survey Saved | The user clicks Save. Use this to write survey_json to your database. |
| Survey Published | The user clicks Publish. Use this to mark the survey as live in your database. |
| Survey Changed | Any time the user makes an edit (debounced). Fires often — use sparingly. |
Most common workflow — save a survey:
The Form Element
Drag SurveyKiln Form onto any page where respondents should fill out and submit surveys.
Minimum size: 600px wide × 500px tall. The form is internally scrollable.
Properties
| Property | Type | Default | What it does |
|---|---|---|---|
| Survey JSON Required | Text | — | The survey to render. Pass json_content from your database. The form will not display without this. |
| Read Only | Yes/No | No | Set to Yes to show a completed response without allowing edits. |
| Initial Answers | Text | empty | Pre-fill the form with answers from a saved response. Pass the response_data JSON. |
| Primary Color | Color | from survey | Override the survey's built-in color to match your app's branding. |
Exposed States
| State | Type | What it contains |
|---|---|---|
| response_json | Text | The respondent's answers as JSON. Populated after submission. Save this to your database. |
| is_complete | Yes/No | yes after the form has been successfully submitted. |
| current_page | Number | Current page number (starts at 1). Use to display "Page 2 of 5". |
| total_pages | Number | Total number of pages in the survey. |
| progress_percent | Number | A number from 0–100. Use to drive a progress bar element. |
Events
| Event | When it fires |
|---|---|
| Form Completed | The respondent clicks Submit and passes validation. Use this to save the response to your database. |
| Page Changed | The respondent navigates to a different page. Use this to update a progress bar or page counter. |
Most common workflow — save a response:
Workflow Actions
Use these to control the Builder and Form from your own workflows. Find them under Element Actions in the workflow editor.
Builder Actions
| Action | Input | What it does |
|---|---|---|
| Set Survey JSON | json (text) |
Load a survey into the builder. The builder switches to editing that survey. |
| Reset Builder | none | Clears the builder and starts a fresh blank survey. |
| Download PDF | none | Generates and downloads a PDF of the survey currently loaded in the builder. |
Form Actions
| Action | Input | What it does |
|---|---|---|
| Set Survey JSON | json (text) |
Load a different survey into the form. Resets all answers. |
| Set Answers | json (text) |
Pre-fill the form with answers from a saved response. |
| Reset Form | none | Clears all answers and returns the respondent to page 1. |
Guide: Build a Survey App
A complete walkthrough for building a survey management system where your users can create and edit surveys.
Step 1 — Set up the database
Create a Survey data type with these fields:
| Field | Type | Notes |
|---|---|---|
| title | Text | A human-readable name for the survey |
| json_content | Text (long) | The full survey definition — use "long text" as this field can be large |
| is_published | Yes/No | Whether the survey is live and accepting responses |
| created_by | User | The user who created it |
| created_at | Date | Set automatically on creation |
Step 2 — Survey list page (/surveys)
Add a Repeating Group showing all surveys for the current user.
Add an Edit button per row that navigates to /survey-builder with the survey's ID in the URL.
Add a Create New Survey button that navigates to /survey-builder with no ID.
Step 3 — Builder page (/survey-builder)
Set the page's Data type to Survey.
Add the SurveyKiln Builder element and fill the page. Set Survey JSON to Current Page Survey's json_content — when this is empty (new survey), the builder starts blank automatically.
Add the save workflow:
Guide: Display a Form to Respondents
Step 1 — Set up the database
Create a Response data type:
| Field | Type | Notes |
|---|---|---|
| survey | Survey | Which survey this response belongs to |
| response_data | Text (long) | The raw JSON response from the form |
| submitted_at | Date | When it was submitted |
| respondent | User | Who submitted it (optional — leave blank for anonymous) |
Step 2 — Take survey page (/survey)
Set the page's Data type to Survey.
Drag the SurveyKiln Form element onto the page (600–800px wide, 600px+ tall). Set Survey JSON to Current Page Survey's json_content.
Add a workflow:
Step 3 — Link users to the form
In a button's Go to page action, select the survey page and set Data to send to the Survey record you want to display.
Guide: View a Submitted Response
Display what a respondent previously submitted in read-only mode.
View response page (/response)
Set the page's Data type to Response.
Drag the SurveyKiln Form element onto the page and set these three properties:
The form renders in read-only mode showing exactly what the respondent submitted. No editing is possible.
Advanced: PDF Download
Generate a downloadable PDF of any survey directly from the builder or from a saved JSON string.
Download from the builder page
Download from a list or detail page
If you want a PDF button without showing the builder, add a hidden Builder element to the page, then load the survey into it before triggering the download:
Advanced: Pre-Fill Answers
Let users revisit and update a previous response, or show a partially completed form.
Via element properties
Set Initial Answers on the Form element to the response_data from a previously saved Response record. All prior answers will be filled in automatically.
Via a workflow action
Advanced: Custom Branding
Every survey has a built-in Primary Color set by the creator. The form uses that color for buttons, progress bars, and selection highlights.
Override the color for all forms site-wide
To make all forms match your app's brand regardless of what color the survey creator chose:
Click the SurveyKiln Form element on your canvas.
In the Properties panel, set Primary Color to your brand color (e.g. #7c3aed).
The same approach applies to the Builder — set its Primary Color property to match your app's theme.
White-label the builder header v1.2.0
Two new Builder properties let you replace Survey Kiln's own branding in the builder header with yours, making it feel like a native part of your product.
| Property | What to set | Result |
|---|---|---|
| Logo URL | A publicly accessible image URL. Recommended size: 160×32px. | Replaces the Survey Kiln logo in the builder header with your own image. |
| App Name | Any text string, e.g. Acme Forms. | Replaces the "Survey Builder" label in the header with your app name. The icon remains visible. |
Advanced: Multi-Page Forms & Progress Tracking
Creating pages in the builder
In the survey builder, click Add a Page in the Components pane to add a new page. There is no "Page Break" question type — pages are managed from the Components panel.
Show a page counter
Add a text element with this dynamic content:
Drive a progress bar
Add a Shape element as the background bar (e.g. 300px wide × 8px tall, gray fill).
Add a second Shape on top as the fill layer. Set its width to:
Database Setup Reference
Recommended data types and fields for a complete survey app.
Survey
| Field | Type | Description |
|---|---|---|
| title | Text | Human-readable survey name |
| json_content | Text (long) | Full survey JSON — the core data field |
| is_published | Yes/No | Whether the survey is accepting responses |
| created_by | User | Creator |
| created_at | Date | Creation timestamp |
| updated_at | Date | Last modified timestamp |
Response
| Field | Type | Description |
|---|---|---|
| survey | Survey | Which survey this belongs to |
| response_data | Text (long) | Full response JSON from SurveyKiln Form's response_json |
| submitted_at | Date | Submission timestamp |
| respondent | User | Who submitted (optional — leave blank for anonymous) |
| respondent_email | Text | Email if collected separately |
Parsing individual answers
Bubble lets you navigate JSON with the :parsed as JSON operator:
Each answer is keyed by the question's ID from the survey definition.
Quick Reference Card
Builder at a glance
Form at a glance
Minimum workflows every app needs
Troubleshooting
The Builder element is blank / not loading
- The Builder needs an explicit height in pixels. "Fit to content" will not work. Use at least 800px.
- Make sure you're on a Bubble plan that allows plugin use.
- Try a hard refresh: Ctrl+Shift+R / Cmd+Shift+R.
The Form element is blank / not loading
- Survey JSON is required. If it's empty or invalid, the form won't render. Confirm you're passing a valid json_content value from your database.
- The Survey record must exist and json_content must not be empty.
- The Form element also needs an explicit height — use at least 500px.
The survey_json state is empty
survey_json only updates after the user makes a change in the builder. If they haven't touched anything, the state may be empty even though a survey is loaded. Use the Survey Saved event instead — it fires with the JSON attached.
Changes are overwritten when I save
This happens when Survey JSON is bound to a live database field that keeps refreshing and reloading the old value. Only set Survey JSON once (on page load) and don't bind it to a data source that auto-refreshes. Use the Set Survey JSON action only when you explicitly want to reload a different survey.
The form submits but response_json is empty
- Read SurveyKiln Form's response_json inside the workflow step that runs after the Form Completed event fires.
- Confirm the workflow trigger is Form Completed — not a button click or page-load event.
The "Download PDF" action does nothing
- Confirm a SurveyKiln Builder element exists on the page (even if hidden). The PDF action requires the builder to be initialized.
- Check your browser's popup blocker — PDF downloads may be blocked for your Bubble app's domain.
The form color doesn't match my brand
Set the Primary Color property on the Form element to your brand color. See Custom Branding.
File uploads — where do files go?
File upload questions store the uploaded file as a base64 data URI inside response_data. The file is embedded directly in the JSON string. For heavy file use in production, contact support for guidance on a custom upload handler.
Changelog
Release history for the Survey Kiln Bubble.io plugin.
Two new Builder properties allow you to replace Survey Kiln's branding in the builder header with your own:
- Logo URL — pass an image URL to replace the builder header logo with your own (recommended 160×32px).
- App Name — replace the "Survey Builder" text with your own app name while keeping the icon.
Seven new Yes/No Builder properties give you precise control over what your users see in the Settings tab:
| Property | Controls |
|---|---|
| Show Settings Tab | Master toggle — hides the entire Settings tab when set to No. |
| Settings - Show Survey Info Section | Survey title and description fields. |
| Settings - Show Schedule Section | Start date and close date scheduling. |
| Settings - Show Thank You Section | Thank you message and confetti toggle. |
| Settings - Show Redirect URL | The redirect URL field within the Thank You section. |
| Settings - Show Styling Section | Background color, font size, and spacing controls. |
| Settings - Show Survey Options | Progress bar, back navigation, PDF download, and shuffle questions toggles. |
Available in the Survey Builder under Settings → Survey Options. Toggle it on and questions will be presented in a randomized order each time a respondent starts the form. The order stays consistent as they navigate through the survey — it only reshuffles on a fresh load.
No changes needed in Bubble — the flag is stored in the survey JSON and works automatically in the Form element when that JSON is loaded.