SurveyRenderer — API Reference
Complete reference for the SurveyRenderer component — a batteries-included survey UI built on top of the useSurvey hook.
Import
import { SurveyRenderer } from 'react-minimal-survey-builder';Props
SurveyRendererPropstypescript
interface SurveyRendererProps {
schema: SurveySchema;
options?: SurveyOptions;
components?: QuestionComponents;
className?: string;
children?: (survey: UseSurveyReturn) => React.ReactNode;
disabled?: boolean;
renderHeader?: (props: RenderHeaderProps) => React.ReactNode;
renderFooter?: (props: RenderFooterProps) => React.ReactNode;
renderComplete?: () => React.ReactNode;
}Props Detail
| Prop | Type | Default | Description |
|---|---|---|---|
schema | SurveySchema | — | Survey schema object (required) |
options | SurveyOptions | {} | Callbacks, initial answers, validators |
components | QuestionComponents | {} | Custom component overrides by question type |
className | string | — | CSS class for the survey container |
children | (survey) => ReactNode | — | Render prop for full layout control |
disabled | boolean | false | Disable all inputs |
renderHeader | (props) => ReactNode | — | Custom header renderer |
renderFooter | (props) => ReactNode | — | Custom navigation footer |
renderComplete | () => ReactNode | — | Custom completion screen |
renderHeader Props
RenderHeaderPropstypescript
interface RenderHeaderProps {
title?: string;
description?: string;
progress: number; // 0–100
currentPage: number; // zero-based page index
totalPages: number;
}renderFooter Props
RenderFooterPropstypescript
interface RenderFooterProps {
hasPrevPage: boolean;
hasNextPage: boolean;
isLastPage: boolean;
prevPage: () => void;
nextPage: () => void;
submit: () => void;
isValid: boolean;
}QuestionComponents
QuestionComponents & Propstypescript
type QuestionComponents = Partial<
Record<QuestionType, React.ComponentType<QuestionComponentProps>>
>;
type QuestionComponentProps<V = AnswerValue> = {
question: Question;
value: V;
onChange: (value: V) => void;
error?: string;
disabled?: boolean;
};Rendering Modes
Default Mode
Renders header, questions, navigation, and completion screen using built-in components. Style via CSS class names (rmsb-*) or the className prop.
Custom Components Mode
Pass components to override specific question types. The layout and navigation remain the defaults.
Render Prop Mode
Pass a function as children for complete control. The function receives the fulluseSurvey return object.
Accessibility
All default question components are WCAG 2.1 AA compliant. Every form field includes:
aria-requiredand nativerequiredon mandatory fieldsaria-invalidwhen validation failsaria-describedbylinking to description and error messages- Proper ARIA roles (
radiogroup,group) on composite controls aria-labelledbyon grouped inputs (radio, checkbox, boolean, rating)aria-checked/aria-pressedon rating buttonsaria-valuemin,aria-valuemax,aria-valuenow,aria-valuetexton slidersrole="alert"witharia-live="assertive"on error messages- Keyboard
:focus-visibleoutlines on all interactive elements
Minimal Example
Minimaltsx
<SurveyRenderer
schema={schema}
options={{ onSubmit: (answers) => console.log(answers) }}
/>Full-Featured Example
Full-Featured Exampletsx
<SurveyRenderer
schema={schema}
className="max-w-xl mx-auto"
disabled={isReadOnly}
components={{
text: CustomTextInput,
rating: StarRating,
}}
options={{
initialAnswers: savedAnswers,
onSubmit: async (answers) => {
await api.post('/responses', answers);
},
onChange: (answers, id) => autosave(answers),
validators: {
email: (v) => (String(v).includes('@') ? null : 'Invalid email'),
},
}}
renderHeader={({ title, progress }) => (
<div>
<h1>{title}</h1>
<progress value={progress} max={100} />
</div>
)}
renderFooter={({ isLastPage, prevPage, nextPage, submit, hasPrevPage }) => (
<div className="flex gap-4">
{hasPrevPage && <button onClick={prevPage}>Back</button>}
<button onClick={isLastPage ? submit : nextPage}>
{isLastPage ? 'Submit' : 'Next'}
</button>
</div>
)}
renderComplete={() => <p>Thanks for your response!</p>}
/>