Home
About
Apps
Blog
Archive
Contact
Theme
Back to Blog
Next.jsSurveyJSReact

NextJs & SurveyJS

December 28, 2021
5 min read
NextJs & SurveyJS

If you got into a situation when you have to build a very complex survey application, you will find yourself looking for solutions that help you get a great result without building the entire thing from scratch.

If you google this you might get multiple solutions that might help you, like Typeform, but you'll get limited either by the pricing or but the limitation of option it provides.

One of the solutions you will get is a library called SurveyJs.

The SurveyJs issues with NextJs

One of the main issues that encounter many developers is that SurveyJs is a Browser-side library and on the other hand NextJs is using server-side rendering or static generation.

Installations

  1. Install SurveyJs
bash
1yarn add survey-react
  1. Create a new file named survey.tsx under pages
javascript
1import dynamic from "next/dynamic";
2import styled from "styled-components";
3
4const SurveyComponent = dynamic(() => import("../components/survey"), {
5  ssr: false,
6});
7const Container = styled.div`
8  margin: 2rem;
9`;
10const Survey = () => {
11  return (
12    <Container>
13      <SurveyComponent />
14    </Container>
15  );
16};
17export default Survey;

As you notice we used dynamic import with ssr: false option provided by Nextjs to make sure our SurveyComponent is not included on server-side.

Read more about dynamic imports from Nextjs here.

  1. Create the SurveyComponent
javascript
1// components/survey/index.tsx
2import * as Survey from "survey-react"; // import surveyjs
3import { questions } from "./content"; // these are the survey questions
4import { Container } from "./styles"; // your styles here
5
6// Modern theme
7import "survey-react/modern.min.css";
8// Default theme
9// import 'survey-react/survey.min.css';
10
11const SurveyComponent = () => {
12  // Apply theme
13  Survey.StylesManager.applyTheme("modern");
14
15  // Create a modal
16  const survey = new Survey.Model(questions);
17
18  // Render the survey
19  return (
20    <Container className="container">
21      <Survey.Survey model={survey} />
22    </Container>
23  );
24};
25
26export default SurveyComponent;
  1. Create the file containing the survey questions
javascript
1// components/survey/content/index.tsx
2
3export const questions = {
4  showQuestionNumbers: "off",
5  pages: [
6    {
7      name: "page1",
8      elements: [
9        {
10          type: "text",
11          name: "name",
12          title: "Name",
13          isRequired: true,
14        },
15      ],
16    },
17  ],
18};

Question types

SurveyJs provide a variety of question types I will try to mention some.

  1. Radio
javascript
1{
2  type: "radiogroup",
3  name: "free_registered_user",
4  title: "Question 1",
5  isRequired: true,
6  description: "Would you like to become a free registered user",
7  choices: ["Yes", "No"],
8}
  1. Dropdown
javascript
1// using static data as choices
2{
3  type: "dropdown",
4  name: "region",
5  title: "Region",
6  choices: ["Africa", "Americas", "Asia", "Europe", "Oceania"],
7},
javascript
1// using API data as choices
2{
3  type: "dropdown",
4  name: "region",
5  title: "Region",
6  isRequired: true,
7  choicesByUrl: {
8    url: "URL_API_HERE", // external API
9    url: "/api/region", // Next API
10  },
11},
  1. Percentages
javascript
1{
2  type: "text",
3  name: "percentage",
4  title: "Some percentage",
5  isRequired: true,
6  inputType: "number",
7  min: 0,
8  max: 100,
9},
  1. Checkbox
javascript
1{
2  type: "checkbox",
3  name: "checkbox",
4  title: "Some checkbox",
5  // isRequired: true,
6  choices: [
7    "Option 1",
8    "Option 2",
9    "Option 3",
10    "Option 4",
11    "Option 5",
12  ],
13},

Widgets

There are also many widgets that you can use. You will find the list of widgets here.

But first to be able to work with these widgets you need to: install surveyjs-widgets

bash
1yarn add surveyjs-widgets

Since they don't support TypScript yet, you will need to create a file named surveyjs-widgets.d.ts and include this line in it.

javascript
1declare module 'surveyjs-widgets';
  1. Import widgets in the SurveyComponent
javascript
1import * as widgets from "surveyjs-widgets";
  1. Import widget styles in our example we will use nouislider
javascript
1import "nouislider/distribute/nouislider.min.css";
  1. And finally, add this inside SurveyComponent
javascript
1widgets.nouislider(Survey);

After that, you can simply add the questions as type: nouislider, and this works for all other widgets.

javascript
1{
2  type: "nouislider",
3  name: "slidePercentage",
4  title:
5    "Some %",
6  // isRequired: true,
7  rangeMin: 0,
8  rangeMax: 1000,
9  // You can install and use the wnumb to customize tooltip numbers like this
10  tooltips: wNumb({
11    decimals: 0,
12  }),
13},

Passing question value to other questions

This is very easy just like in the example below:

javascript
1{
2  type: "dropdown",
3  name: "region",
4  title: "Region",
5  choices: ["Africa", "Americas", "Asia", "Europe", "Oceania"],
6},
7{
8  type: "dropdown",
9  name: "country",
10  title: "Country",
11  choicesByUrl: {
12    url: "https://restcountries.eu/rest/v2/region/{region}",
13    valueName: "name",
14  },
15},

The same goes for other question properties like: visibleIf: "{number} > 4"

Save survey state to local storage

To prevent losing questions answers on page reload SurveyJs provides a way of doing it, by saving survey data in local storage. You can call this inside your SurveyComponent

javascript
1// /components/survey/index.tsx
2survey.sendResultOnPageNext = true
3const storageName = "SurveyNextjs"
4function saveSurveyData(survey: any) {
5  let data = survey.data
6  data.pageNo = survey.currentPageNo
7  window.localStorage.setItem(storageName, JSON.stringify(data))
8  console.log(data)
9}
10survey.onPartialSend.add(function (survey) {
11  saveSurveyData(survey)
12})
13const prevData = window.localStorage.getItem(storageName) || null
14if (prevData) {
15  let data = JSON.parse(prevData)
16  survey.data = data
17  if (data.pageNo) {
18    survey.currentPageNo = data.pageNo
19  }
20}

Save data on survey complete

javascript
1survey.onComplete.add(function (survey, options) {
2  saveSurveyData(survey);
3  console.log(survey.data);
4  // window.location.href = "/survey/finish";
5});

I hope you found that interesting, informative, and entertaining. I would be more than happy to hear your remarks and thoughts about this solution.

If you think other people should read this post. Tweet, share and Follow me on Twitter for the next articles.

Some Refs