Conditional Fields
Show and hide questions dynamically based on previous answers using visibleIf expressions.
Schema
schema.tstsx
import type { SurveySchema } from 'react-minimal-survey-builder';
const schema: SurveySchema = {
id: 'conditional-demo',
title: 'Event Registration',
pages: [
{
id: 'basics',
title: 'Basic Information',
questions: [
{
id: 'name',
type: 'text',
label: 'Full name',
required: true,
},
{
id: 'attendee-type',
type: 'radio',
label: 'Are you attending as...',
required: true,
options: [
{ label: 'Individual', value: 'individual' },
{ label: 'Company representative', value: 'company' },
{ label: 'Student', value: 'student' },
],
},
// Only visible when attendee-type is "company"
{
id: 'company-name',
type: 'text',
label: 'Company name',
required: true,
visibleIf: "{attendee-type} === 'company'",
},
{
id: 'company-size',
type: 'select',
label: 'Company size',
visibleIf: "{attendee-type} === 'company'",
options: [
{ label: '1–10', value: 'small' },
{ label: '11–100', value: 'medium' },
{ label: '100+', value: 'large' },
],
},
// Only visible when attendee-type is "student"
{
id: 'university',
type: 'text',
label: 'University / Institution',
required: true,
visibleIf: "{attendee-type} === 'student'",
},
{
id: 'student-id',
type: 'text',
label: 'Student ID',
visibleIf: "{attendee-type} === 'student'",
validation: [
{ type: 'pattern', value: '^[A-Z0-9]+$', message: 'Uppercase letters and numbers only' },
],
},
],
},
{
id: 'preferences',
title: 'Preferences',
questions: [
{
id: 'meal',
type: 'radio',
label: 'Meal preference',
options: [
{ label: 'Standard', value: 'standard' },
{ label: 'Vegetarian', value: 'vegetarian' },
{ label: 'Vegan', value: 'vegan' },
{ label: 'Other', value: 'other' },
],
},
{
id: 'meal-details',
type: 'text',
label: 'Please specify your dietary requirements',
required: true,
visibleIf: "{meal} === 'other'",
},
{
id: 'needs-accommodation',
type: 'radio',
label: 'Do you need accommodation?',
options: [
{ label: 'Yes', value: 'yes' },
{ label: 'No', value: 'no' },
],
},
{
id: 'check-in',
type: 'date',
label: 'Check-in date',
required: true,
visibleIf: "{needs-accommodation} === 'yes'",
},
{
id: 'check-out',
type: 'date',
label: 'Check-out date',
required: true,
visibleIf: "{needs-accommodation} === 'yes'",
},
],
},
// This entire page only appears for company attendees
{
id: 'sponsorship',
title: 'Sponsorship Opportunities',
visibleIf: "{attendee-type} === 'company'",
questions: [
{
id: 'sponsor-interest',
type: 'radio',
label: 'Interested in sponsoring the event?',
options: [
{ label: 'Yes', value: 'yes' },
{ label: 'No', value: 'no' },
],
},
{
id: 'sponsor-tier',
type: 'select',
label: 'Sponsorship tier',
visibleIf: "{sponsor-interest} === 'yes'",
options: [
{ label: 'Gold ($10,000)', value: 'gold' },
{ label: 'Silver ($5,000)', value: 'silver' },
{ label: 'Bronze ($1,000)', value: 'bronze' },
],
},
],
},
],
settings: {
showProgress: true,
allowBack: true,
},
};Rendering
Componenttsx
import { SurveyRenderer } from 'react-minimal-survey-builder';
function EventRegistration() {
return (
<SurveyRenderer
schema={schema}
options={{
onSubmit: async (answers) => {
console.log('Registration:', answers);
},
onChange: (answers, questionId) => {
// Log visibility changes for debugging
console.log(`${questionId} changed to:`, answers[questionId]);
},
}}
/>
);
}How It Works
Question-level branching
company-name and company-size only appear when attendee-type is "company".university and student-id appear for "student". Hidden fields are excluded from validation.
Page-level branching
The entire Sponsorship Opportunities page is only shown to company representatives. The progress bar and page count adjust automatically.
Nested conditions
sponsor-tier has a nested condition — it only appears when the sponsorship page is visible AND sponsor-interest is "yes".
Remember
- - Hidden questions preserve their answers — they're just not shown or validated.
- - If a condition fails to parse, the question is shown by default (fail-open).
- - Use the Conditional Logic guide for the full expression syntax.