SurveyJS v2.4.0
Released: November 26, 2025
SurveyJS v2.4.0 introduces several enhancements to survey performance and usability and includes important breaking changes, including stricter HTML ID handling, improved control over lazy-loaded choices, and a new API for saving and restoring the survey's UI state.
[Breaking Change] Action buttons now always use unique id values
In previous versions, certain survey and Survey Creator configurations could generate action buttons with duplicate id attributes, which is an invalid HTML pattern. Starting with this release, all action buttons have unique id values.
If your code or tests rely on specific action button IDs, review and update those references to ensure they continue to work correctly.
[Breaking Change] choicesByUrl no longer loads choices when lazy loading is enabled
Dropdown and Tag Box questions can load choices in two ways:
- All at once, using the
choicesByUrlconfiguration. - On demand, using the
onChoicesLazyLoadfunction whenchoicesLazyLoadEnabledistrue.
Previously, if both were configured, choicesByUrl would still load all choices up front. Starting with SurveyJS v2.4.0, choicesByUrl is ignored when lazy loading is enabled. Instead, its configuration is now available inside onChoicesLazyLoad, allowing you to read the URL and load the data yourself:
const surveyJson = {
"elements": [{
"name": "question1",
"type": "dropdown",
"choicesByUrl": {
"url": "https://example1.com"
},
"choicesLazyLoadEnabled": true
},
{
"name": "question2",
"type": "tagbox",
"choicesByUrl": {
"url": "https://example2.com"
},
"choicesLazyLoadEnabled": true
}]
}
// ...
// Omitted: `SurveyModel` creation
// ...
survey.onChoicesLazyLoad.add((_, options) => {
if (options.question.choicesByUrl.url) {
// Load choices from the specified endpoint URL
}
});
You are affected if a Dropdown or Tag Box question defines both choicesByUrl and choicesLazyLoadEnabled. To restore previous behavior, disable choicesLazyLoadEnabled. To adopt lazy loading, update your onChoicesLazyLoad handler to fetch from the URL defined in choicesByUrl.
New Survey UI State API
SurveyJS Form Library supports scenarios where a respondent leaves a survey unfinished and returns later. To improve this experience, SurveyJS v2.4.0 introduces a UI state object that stores the following:
- Whether question boxes are expanded or collapsed
- The last visited question name
- The active panel index in a Dynamic Panel
You can save this UI state in the respondent's localStorage and restore it when the survey loads again. Use the uiState property to access the current state and handle the onUIStateChanged event to track updates:
// ...
// Omitted: `SurveyModel` creation
// ...
survey.onUIStateChanged.add((_, options) => {
const state = survey.uiState;
// Save the state in the `localStorage`
});
New Help Topics
Survey Creator: How to Create a Form with File Upload
Bug Fixes and Minor Enhancements
Form Library
- Binding a Dynamic Panel with a Checkboxes question using
valuePropertyNamestopped working correctly (#10633) - [Survey Creator] Preview tab: "Show Invisible Elements" doesn't display invisible matrix columns (#10631)
- Dynamic Matrix: Rows do not appear after setting its data to an empty array and then assigning a new array (#10622)
How to Update SurveyJS Libraries in Your Application
Angular
npm i survey-core@v2.4.0 survey-angular-ui@v2.4.0 --save
npm i survey-creator-core@v2.4.0 survey-creator-angular@v2.4.0 --save
npm i survey-analytics@v2.4.0 --save
npm i survey-pdf@v2.4.0 --save
React
npm i survey-core@v2.4.0 survey-react-ui@v2.4.0 --save
npm i survey-creator-core@v2.4.0 survey-creator-react@v2.4.0 --save
npm i survey-analytics@v2.4.0 --save
npm i survey-pdf@v2.4.0 --save
Vue.js
npm i survey-core@v2.4.0 survey-vue3-ui@v2.4.0 --save
npm i survey-creator-core@v2.4.0 survey-creator-vue@2.4.0 --save
npm i survey-analytics@2.4.0 --save
npm i survey-pdf@2.4.0 --save
HTML/CSS/JavaScript
<link href="https://unpkg.com/survey-core@2.4.0/survey-core.min.css" type="text/css" rel="stylesheet">
<script type="text/javascript" src="https://unpkg.com/survey-core@2.4.0/survey.core.min.js"></script>
<script type="text/javascript" src="https://unpkg.com/survey-js-ui@2.4.0/survey-js-ui.min.js"></script>
<script src="https://unpkg.com/survey-core@2.4.0/themes/index.min.js"></script>
<script src="https://unpkg.com/survey-creator-core@2.4.0/themes/index.min.js"></script>
<link href="https://unpkg.com/survey-creator-core@2.4.0/survey-creator-core.min.css" type="text/css" rel="stylesheet">
<script src="https://unpkg.com/survey-creator-core@2.4.0/survey-creator-core.min.js"></script>
<script src="https://unpkg.com/survey-creator-js@2.4.0/survey-creator-js.min.js"></script>
<link href="https://unpkg.com/survey-analytics@2.4.0/survey.analytics.min.css" rel="stylesheet">
<script src="https://unpkg.com/survey-analytics@2.4.0/survey.analytics.min.js"></script>
<script src="https://unpkg.com/survey-pdf@2.4.0/survey.pdf.min.js"></script>
<script src="https://unpkg.com/survey-pdf@2.4.0/pdf-form-filler.min.js"></script>