Quick Start
Get a survey running in under 5 minutes.
Step 1: Define a Schema
Every survey starts with a schema — a JSON object that describes your pages, questions, and settings.
schema.tstsx
import type { SurveySchema } from 'react-minimal-survey-builder';
const schema: SurveySchema = {
id: 'feedback-form',
title: 'Customer Feedback',
description: 'We value your feedback!',
pages: [
{
id: 'page1',
title: 'About You',
questions: [
{
id: 'name',
type: 'text',
label: 'What is your name?',
required: true,
placeholder: 'Enter your name',
},
{
id: 'email',
type: 'email',
label: 'Email address',
required: true,
validation: [
{ type: 'email', message: 'Please enter a valid email' },
],
},
],
},
{
id: 'page2',
title: 'Your Feedback',
questions: [
{
id: 'satisfaction',
type: 'radio',
label: 'How satisfied are you?',
required: true,
options: [
{ label: 'Very Satisfied', value: 'very-satisfied' },
{ label: 'Satisfied', value: 'satisfied' },
{ label: 'Neutral', value: 'neutral' },
{ label: 'Dissatisfied', value: 'dissatisfied' },
],
},
{
id: 'comments',
type: 'textarea',
label: 'Additional comments?',
placeholder: 'Tell us more...',
visibleIf: '{satisfaction} === "dissatisfied"',
},
],
},
],
settings: {
showProgress: true,
allowBack: true,
submitText: 'Send Feedback',
},
};Step 2: Render the Survey
Option A: Drop-in Component
Use SurveyRenderer for a ready-to-go survey with built-in UI:
Option A: SurveyRenderertsx
import { SurveyRenderer } from 'react-minimal-survey-builder';
function FeedbackPage() {
return (
<SurveyRenderer
schema={schema}
options={{
onSubmit: async (answers) => {
await fetch('/api/feedback', {
method: 'POST',
body: JSON.stringify(answers),
});
alert('Thank you for your feedback!');
},
}}
/>
);
}Option B: Headless Hook
Use useSurvey for full control over rendering:
Option B: useSurvey Hooktsx
import { useSurvey } from 'react-minimal-survey-builder';
function FeedbackPage() {
const {
answers, setAnswer, getVisibleQuestions,
errors, getError, validate,
currentPageIndex, totalPages,
nextPage, prevPage, submit,
progress,
} = useSurvey(schema, {
onSubmit: (answers) => console.log(answers),
});
const questions = getVisibleQuestions();
return (
<form onSubmit={(e) => { e.preventDefault(); submit(); }}>
{/* Progress bar */}
<div style={{ width: `${progress}%`, height: 4, background: 'blue' }} />
{questions.map((q) => (
<div key={q.id}>
<label>{q.label}{q.required && ' *'}</label>
{q.type === 'text' && (
<input
value={(answers[q.id] as string) ?? ''}
onChange={(e) => setAnswer(q.id, e.target.value)}
placeholder={q.placeholder}
/>
)}
{/* ...handle other types */}
{getError(q.id) && <span className="error">{getError(q.id)}</span>}
</div>
))}
<div>
{currentPageIndex > 0 && <button type="button" onClick={prevPage}>Back</button>}
{currentPageIndex < totalPages - 1
? <button type="button" onClick={nextPage}>Next</button>
: <button type="submit">Submit</button>
}
</div>
</form>
);
}Step 3: Use the Builder (Optional)
Let end-users create surveys visually with the drag & drop builder:
SurveyBuildertsx
import { useState } from 'react';
import { SurveyBuilder } from 'react-minimal-survey-builder/builder';
import type { SurveySchema } from 'react-minimal-survey-builder';
function BuilderPage() {
const [schema, setSchema] = useState<SurveySchema>({
id: 'new-survey',
pages: [{ id: 'page1', questions: [] }],
});
return (
<div>
<SurveyBuilder
value={schema}
onChange={setSchema}
showPreview
showJson
/>
<button onClick={() => console.log(JSON.stringify(schema, null, 2))}>
Export Schema
</button>
</div>
);
}What's Next?
- - Learn about the Schema format
- - Explore the useSurvey hook
- - Add validation rules
- - Set up conditional logic
- - Try the live demo