---
title: NPS Survey Question
product: Form Library
description: Net Promoter Score survey question with multiple follow-up questions and predefined conditional logic, a free example for JavaScript.
framework: React
source: https://surveyjs.io/form-library/examples/nps-question/reactjs
index: https://surveyjs.io/form-library/examples/overview.md
---

# NPS Survey Question (React)

NPS (net promoter score) is a metric used to evaluate customer loyalty and business growth opportunities. To measure NPS, respondents should rate on a scale of 0 to 10 how likely they would recommend your product or service to a friend or colleague. You can also ask follow-up questions to solicit additional feedback, for instance: "What is the reason for your score?". This demo shows how you can use the SurveyJS Form Library to create an NPS question and additional follow-up questions with predefined conditional logic.

To create an NPS question, use the [Rating](https://surveyjs.io/form-library/examples/rating-scale) question type. It allows you to score answers to a question on a simple zero-to-ten scale. Define an object with the `type` property set to `"rating"` and add it to the [`elements`](/form-library/documentation/pagemodel#elements) array.

Use the [`rateMin`](/form-library/documentation/questionratingmodel#rateMin) and [`rateMax`](/form-library/documentation/questionratingmodel#rateMax) properties to limit the range of possible answers. Optionally, you can set the [`minRateDescription`](/form-library/documentation/questionratingmodel#minRateDescription) and [`maxRateDescription`](/form-library/documentation/questionratingmodel#maxRateDescription) properties to add descriptions for the extreme scale values (0 and 10).

If users should not leave the NPS question unanswered, enable its [`isRequired`](/form-library/documentation/questionratingmodel#isRequired) property as shown in this demo.

## Follow-Up Questions

Follow-up questions allow customers to elaborate on their score and help you better understand customer needs. Typically, follow-up questions ask respondents to select one or more values from a set of choices or leave a comment.

### Choice-Based Questions

SurveyJS Form Library includes multiple choice-based question types: [Dropdown](https://surveyjs.io/Examples/Library?id=questiontype-dropdown), [Radiogroup](https://surveyjs.io/Examples/Library?id=questiontype-radiogroup), [Checkbox](https://surveyjs.io/Examples/Library?id=questiontype-checkbox), [Image Picker](https://surveyjs.io/Examples/Library?id=questiontype-imagepicker). In this demo, respondents are asked to select features they value the most. For this question, the best suitable type is Checkbox because it allows users to select multiple text values.

To create a Checkbox question, add an object with the `type` property set to `"checkbox"` to the [`elements`](/form-library/documentation/pagemodel#elements) array. Use the [`choices`](/form-library/documentation/questioncheckboxmodel#choices) array to specify choice values. Populate it with primitive values as shown in this demo if you do not need to change display texts. Otherwise, fill the array with objects in which the `value` field contains a choice value and the `text` field contains display text for the value. 

Choice-based questions can include special choices: None, Select All, Other. To enable them, use the following Boolean properties:

- [`showNoneItem`](/form-library/documentation/questioncheckboxmodel#showNoneItem)     
Adds the None choice item. Use the [`noneText`](/form-library/documentation/questioncheckboxmodel#noneText) property to change the item's display text.

- [`showSelectAllItem`](/form-library/documentation/questioncheckboxmodel#showSelectAllItem) (supported by Checkbox questions only)     
Adds the Select All choice item. Use the [`selectAllText`](/form-library/documentation/questioncheckboxmodel#selectAllText) property to change the item's display text.

- [`showOtherItem`](/form-library/documentation/questioncheckboxmodel#showOtherItem)            
Adds the Other choice item. Use the [`otherText`](/form-library/documentation/questioncheckboxmodel#otherText) property to change the item's display text.

This demo enables the Other item.

You can use data validation to impose restrictions on selected values. For example, this demo shows how to limit the number of selected choices. To define validation rules, use the [`validators`](/form-library/documentation/questioncheckboxmodel#validators) array.

If you want to arrange choices in multiple columns, specify the [`colCount`](/form-library/documentation/questioncheckboxmodel#colCount) property. In this demo, `colCount` is set to 2.

### Open-Ended Questions

To add an open-ended question to your survey, use the [Text](https://surveyjs.io/Examples/Library?id=questiontype-text) or [Comment](https://surveyjs.io/Examples/Library?id=questiontype-comment) question type. Unlike Text, the Comment type supports multi-line input. The NPS survey in this demo contains two Comment questions. To create them, add objects to the [`elements`](/form-library/documentation/pagemodel#elements) array and set their `type` property to `"comment"`. Optionally, set the [`maxLength`](/form-library/documentation/questioncommentmodel#maxLength) property to specify the maximum answer length in characters.

### Conditional Visibility

Conditional visibility is built upon [Boolean expressions](/form-library/documentation/design-survey-conditional-logic#conditional-visibility). To display different follow-up questions based on the NPS score, assign a Boolean expression to the [`visibleIf`](/form-library/documentation/Question#visibleIf) property of each follow-up question. A question is visible only when its expression evaluates to `true`. For example, the following expression displays the question only if the NPS score is 9 or higher:

```js
visibleIf: "{nps_score} >= 9"
```

If you also want to display different [Complete pages](/form-library/documentation/design-survey-create-a-multi-page-survey#complete-page) depending on the NPS score, specify the [`completedHtmlOnCondition`](/form-library/documentation/surveymodel#completedHtmlOnCondition) property. It accepts an array where each object specifies a Boolean expression and HTML markup to display when this expression evaluates to `true`:

```js
{
  "expression": "{some-question} = 0",
  "html": "<p>My custom HTML markup</p>"
}
```

If none of the expressions evaluates to `true`, the survey displays the markup specified by the [`completedHtml`](/form-library/documentation/surveymodel#completedHtml) property. In this demo, this markup is displayed when the NPS score is 6 or lower.

## Files

### `public/index.html`

```html
<div id="surveyElement" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; min-height: 100%; height:100%"></div>
```

### `src/SurveyComponent.jsx`

```js
import React from "react";
import { Model } from "survey-core";
import { Survey } from "survey-react-ui";
import "survey-core/survey-core.min.css";
import "./index.css";
import { json } from "./json";

function SurveyComponent() {
    const survey = new Model(json);
    survey.onComplete.add((sender, options) => {
        console.log(JSON.stringify(sender.data, null, 3));
    });
    survey.data = {
        "nps-score": 9,
        "promoter-features": [
            "performance",
            "ui"
        ]
    };
    return (<Survey model={survey} />);
}

export default SurveyComponent;
```

### `src/index.css`

```css
/* You can add your custom CSS here. */
```

### `src/index.js`

```js
import React from "react";
import { createRoot } from "react-dom/client";
import SurveyComponent from "./SurveyComponent";

const root = createRoot(document.getElementById("surveyElement"));
root.render(<SurveyComponent />);
```

### `src/json.js`

```js
export const json = {
  "completedHtmlOnCondition": [
   {
    "expression": "{nps-score} <= 6 or {rebuy} = false",
    "html": {
     "default": "Thanks for your feedback! We highly value all ideas and suggestions from our customers, whether they're positive or critical. In the future, our team might reach out to you to learn more about how we can further improve our product so that it exceeds your expectations.",
     "fr": "Merci pour vos commentaires! Nous accordons une grande importance à toutes les idées et suggestions de nos clients, qu'elles soient positives ou critiques. À l'avenir, notre équipe pourrait vous contacter pour en savoir plus sur la façon dont nous pouvons encore améliorer notre produit afin qu'il dépasse vos attentes."
    }
   },
   {
    "expression": "{nps-score} = 6 or {nps-score} = 7",
    "html": {
     "default": "Thanks for your feedback. Our goal is to create the best possible product, and your thoughts, ideas, and suggestions play a major role in helping us identify opportunities to improve.",
     "fr": "Merci pour vos commentaires. Notre objectif est de créer le meilleur produit possible, et vos réflexions, idées et suggestions jouent un rôle majeur pour nous aider à identifier les opportunités d'amélioration."
    }
   },
   {
    "expression": "{nps-score} >= 8",
    "html": {
     "default": "Thanks for your feedback. It's great to hear that you're a fan of our product. Your feedback helps us discover new opportunities to improve it and make sure you have the best possible experience.",
     "fr": "Merci pour vos commentaires. Nous sommes ravis d'entendre que vous avez apprécié notre produit. Vos commentaires nous aident à découvrir de nouvelles opportunités pour l'améliorer et vous assurer la meilleure expérience possible."
    }
   }
  ],
  "pages": [
    {
      "name": "page1",
      "elements": [
        {
          "type": "rating",
          "name": "nps-score",
          "title": {
            "default": "On a scale from 0 to 10, how likely are you to recommend us to a friend or colleague?",
            "fr": "Sur une échelle de 0 à 10, quelle est la probabilité que vous recommandiez notre produit à un ami ou à un collègue?"
          },
          "rateMin": 0,
          "rateMax": 10,
          "minRateDescription": {
            "default": "Very unlikely",
            "fr": "Très improbable"
          },
          "maxRateDescription": {
            "default": "Very likely",
            "fr": "Très probable"
          },
          "rateDescriptionLocation": "bottom"
        },
        {
          "type": "comment",
          "name": "disappointing-experience",
          "visibleIf": "{nps-score} <= 5",
          "title": {
            "default": "How did we disappoint you and what can we do to make things right?",
            "fr": "Nous n'avons pas été a la hauteur de vos attentes, comment pouvons-nous améliorer?"
          },
          "maxLength": 300
        },
        {
          "type": "comment",
          "name": "improvements-required",
          "visibleIf": "{nps-score} >= 6",
          "title": {
            "default": "What can we do to make your experience more satisfying?",
            "fr": "Que pouvons-nous faire pour rendre votre expérience plus satisfaisante?"
          },
          "maxLength": 300
        },
        {
          "type": "checkbox",
          "name": "promoter-features",
          "visibleIf": "{nps-score} >= 9",
          "title": {
            "default": "Which of the following features do you value the most?",
            "fr": "Laquelle des fonctionnalités suivantes appréciez-vous le plus ?"
          },
          "description": {
            "default": "Please select no more than three features.",
            "fr": "Veuillez ne pas sélectionner plus de trois fonctionnalités."
          },
          "isRequired": true,
          "choices": [
            {
              "value": "performance",
              "text": "Performance"
            },
            {
              "value": "stability",
              "text": {
                "default": "Stability",
                "fr": "Stabilité"
              }
            },
            {
              "value": "ui",
              "text": {
                "default": "User interface",
                "fr": "Interface utilisateur"
              }
            },
            {
              "value": "complete-functionality",
              "text": {
                "default": "Complete functionality",
                "fr": "Ensemble des fonctionnalités"
              }
            },
            {
              "value": "learning-materials",
              "text": {
                "default": "Learning materials (documentation, demos, code examples)",
                "fr": "Matériel d'apprentissage (documentation, démos, exemples de code)"
              }
            },
            {
              "value": "support",
              "text": {
                "default": "Quality support",
                "fr": "Accompagnement de qualité"
              }
            }
          ],
          "showOtherItem": true,
          "otherPlaceholder": {
            "default": "Please specify...",
            "fr": "Veuillez préciser..."
          },
          "otherText": {
            "default": "Other features",
            "fr": "Autres fonctionnalités"
          },
          "colCount": 2,
          "maxSelectedChoices": 3
        }
      ]
    },
    {
      "name": "page2",
      "elements": [
        {
          "type": "boolean",
          "name": "rebuy",
          "title": {
            "default": "Would you buy our product again?",
            "fr": "Achèteriez-vous à nouveau notre produit?"
          }
        },
      ]
    },
    {
      "name": "page3",
      "elements": [
        {
          "type": "radiogroup",
          "name": "testimonial",
          "title": {
            "default": "Would you mind providing us a brief testimonial for the website?",
            "fr": "Accepteriez-vous de rédiger un bref commentaire pour notre site Internet?"
          },
          "choices": [
            {
              "value": "yes",
              "text": {
                "default": "Sure!",
                "fr": "Bien sur!"
              }
            },
            {
              "value": "no",
              "text": {
                "default": "No",
                "fr": "Non merci."
              }
            }
          ]
        },
        {
          "type": "text",
          "name": "email",
          "visibleIf": "{testimonial} = 'yes'",
          "title": {
            "default": "What is your email address?",
            "fr": "Quelle est votre adresse e-mail?"
          },
          "validators": [
            {
              "type": "email"
            }
          ],
          "placeholder": {
            "default": "Enter your email here",
            "fr": "Veuillez saisir votre adresse e-mail ici"
          }
        }
      ]
    }
  ],
  "showPrevButton": false,
  "completeText": {
   "fr": "Envoyer"
  },
  "widthMode": "static",
  "width": "1000px"
 };
```

### `src/theme.js`

```js
export const themeJson = {};
```

### `package.json`

```json
{
  "dependencies": {
    "react": "latest",
    "react-dom": "latest",
    "survey-core": "latest",
    "survey-react-ui": "latest"
  },
  "devDependencies": {
    "react-scripts": "latest"
  }
}
```

## Other Frameworks

- [Angular](https://surveyjs.io/form-library/examples/nps-question/angular.md)
- [Vue 3](https://surveyjs.io/form-library/examples/nps-question/vue3js.md)
- [jQuery](https://surveyjs.io/form-library/examples/nps-question/jquery.md)
- [Vanilla JS](https://surveyjs.io/form-library/examples/nps-question/vanillajs.md)
