Installing & configuring NPS surveys
An overview of how to install Vitally's NPS and ensure the right users are polled at the right time
First, you'll want to ensure the NPS is enabled. To do that, navigate to the NPS section of your Account Settings (or get there via Quick Jump) and click the switch to enable it.
Once you do, you'll see this configuration page.

You have these options when configuring which users should be surveyed.
'Age' of the user (in days)
Specify a non-zero number here if you'd like to only survey users who've used your product for a minimum amount of time.
Important: By default, we compare each user against the first time we saw the user use your product. So if you are installing Vitally for the first time and you specify a value of 7 here, that means it'll take 7 days before any user sees a survey. However, you can tell us when a user started using your product by sending a
createdAt
user trait when you identify the user (using the Vitally.js library). If you send us a createdAt
trait, we'll use that value when determining if a user should see a survey.Minimum sessions
Specify a non-zero number here if you'd like to only survey users who have logged a minimum number of sessions in your product. Note that sessions are unique per day - i.e. a user has a maximum of one session on any given day. Thus, if you specify 5 here, that means a user must use your product over 5 unique days before seeing a survey.
Important: Unlike the 'age' option above, there's no way to tell us how many sessions a user has had with your product programmatically. So if you are installing Vitally for the first time and you specify a value of 5 here, it'll take at least 5 days (and often more) before any user sees a survey. To avoid that, you can specify 0 here and set the
createdAt
user trait documented above to start collecting NPS survey responses immediately.Consecutive sessions to show a survey
Users are busy, so often, they'll not want to submit an NPS survey. This option allows you to configure how many consecutive sessions a user should be shown a survey only if the survey is dismissed in each session.
For example, if you specify a value of 3 here, that means we'll show the survey to the user for (up to) 3 consecutive sessions. If they dismiss the survey each time, then we'll stop showing the survey from their 4th session onward.
Again, remember that sessions are unique per day. So if a user dismisses the survey at 12:01 AM on Tuesday, we won't show the user another survey until 12:01 AM Wednesday (at the earliest).
'Wait time' before showing a new survey
Once a survey is submitted OR the user last dismisses a survey (according to the 'consecutive sessions' option specified above), this option lets you specify the number of months to wait before showing that user another survey.
Only show surveys to users at accounts matching a Playbook's rules
Playbooks give you the ability to perform automated actions on accounts that meet certain conditions. By default, we'll show the NPS survey to all users that meet the above requirements, but you can filter that dataset even further using Playbooks.
The possibilities are endless here, but here are a few examples you may want to consider:
- Only show the survey to users at subscribed, paying customers (i.e. omit trials)
- Only show the survey to users at subscribed customers that are set to renew within the next 2 weeks
- Only show the survey to users at your 'Enterprise' accounts
NPS surveys are potentially shown to your users once you install Vitally.js, our Javascript library. Here's how to do just that!
Step-by-step details on how to install our Javascript snippet and use the Javascript API to identify each user & account can be found here as well as in the NPS configuration page in your account.
Best practices when using Vitally.js for NPS
- Identify the date the user started an account with your product via the
createdAt
trait. If you send us this trait, we'll use it when determining if a user is 'old' enough to see an NPS survey (see the configuration options for more details). - You should call
Vitally.user
andVitally.account
in each session, but you only need to do so once. If you have already installed Vitally.js to track your users and their product usage, you do not need to do so again for NPS. - You can only use
Vitally.track
on paid plans - Vitally.track is an API that allows you to track interactions a user has with your product. It is only supported on paid plans with access to product analytics. If you try to use it on our "Free NPS" plan, we will discard your tracks.
Once you've installed Vitally.js and have identified the logged-in user and account, call
Vitally.nps('survey')
to potentially show the survey to the logged-in user. The survey will only be shown if the user matches the criteria of your configuration while NPS is enabled.Vitally.nps('survey')
also optionally takes a second argument of options that lets you further customize the survey displayed to users.Option | Valid Types | Details |
productName | string | When specified and you do not overwrite our default question, we'll inject this value into the question "👋 there! Quick question - how likely are you to recommend {productName} to others?" |
delay | number | Specifies the amount of time in milliseconds we'll wait to show a survey to a user that should see it. This defaults to 5000ms (5 seconds). Increase or decrease based on the initial app experience your users have. |
primaryColor | string | Specifies the color to use in buttons. Defaults to a purple color: #6457D |
npsQuestion | string or a function that returns a string | If you provide a function, it is given the productName as a parameter (see below). Overwrites our default question: "👋 there! Quick question - how likely are you to recommend {productName} to others?" |
followUpTitle | string or a function that returns a string | If you provide a function, it is given the productName and score as a parameter (see below). Overwrites the title displayed to users after they submit a score. Defaults to "Thank you for your feedback 🙏" |
followUpSubtitle | string or a function that returns a string | If you provide a function, it is given the productName and score as a parameter (see below). Overwrites the sentence displayed below followUpTitle . Defaults to "Mind letting us know why you chose a {score}?" |
thanksTitle | string or a function that returns a string | If you provide a function, it is given the productName , score , and feedback as a parameter (see below). Overwrites the title displayed to users that submit text feedback. Defaults to the succinct "Thanks!" |
thanksSubtitle | string or a function that returns a string | If you provide a function, it is given the productName , score , and feedback as a parameter (see below). Overwrites the sentence displayed below thanksTitle . Defaults to "We sincerely appreciate your feedback." |
minLabel | string or a function that returns a string | If you provide a function, it is given the productName as a parameter (see below). Overwrites the text display below "0" |
maxLabel | string or a function that returns a string | If you provide a function, it is given the productName as a parameter (see below). Overwrites the text display below "10" |
placeholderText | string or a function that returns a string | If you provide a function, it is given the productName and score as a parameter (see below). Overwrites the placeholder text in the feedback box |
submitText | string or a function that returns a string | If you provide a function, it is given the productName and score as a parameter (see below). Overwrites the text of the button to submit feedback |
dismissText | string or a function that returns a string |
If you provide a function, it is given the productName and score as a parameter (see below). Overwrites the text of the button to dismiss the feedback modal |
Putting this all together, if you want to overwrite all options (with static strings), you'd make an API call like this:
Vitally.nps('survey', {
productName: 'Pied Piper',
delay: 1000,
primaryColor: '#000000',
npsQuestion: 'Hey yo! You like Pied Piper?',
followUpTitle: 'Solid feedback my dude!',
followUpSubtitle: 'Mind elaborating a bit though?',
thanksTitle: 'You are amazing!',
thanksSubtitle: 'Bye for now'
});
For more advanced configuration, you can specify functions for arguments and dynamically change the copy users see based on their feedback:
Vitally.nps('survey', {
productName: 'Pied Piper',
delay: 1000,
primaryColor: '#000000',
npsQuestion: ({ productName }) => `Hey yo! You like ${productName}?`,
followUpTitle: ({ productName, score }) => {
return score < 7 ? `Oh no! What can we do better?`: `Solid feedback my dude!`;
},
followUpSubtitle: ({ productName, score }) => {
return score < 7 ? `How can we get that score up?`: `Mind elaborating a bit though?`;
},
thanksTitle: ({ productName, score, feedback }) => {
return score < 7 ? `Thanks. We'll do better - promise!`: `You are amazing!`;
},
thanksSubtitle: ({ productName, score, feedback }) => {
return score < 7 ? `Until next time.`: `Bye for now.`;
},
minLabel: 'No chance',
maxLabel: 'Definitely!',
placeholderText: ({ productName, score }) => {
return score <= 7 ? 'I wish it could...' : 'I love it because...';
},
submitText: 'Submit my response',
dismissText: 'Let me get back to work'
});
Since
Vitally.nps('survey')
obeys your NPS configuration, testing the survey display could get a bit annoying. To force display the survey, replace survey
with show
.Vitally.nps('show', {
productName: 'Pied Piper',
delay: 0
});
Important: Don't ship with
show
though - use survey
in production. Otherwise, you'll be annoying your users a good bit :)show
still sends submitted responses to your Vitally account though. If you'd rather that not happen (i.e. you only want to see what the survey experience is like), replace show
with test
.Vitally.nps('test', {
productName: 'Pied Piper',
delay: 0
});
To summarize:
Vitally.nps('survey')
- Displays a survey to users only if your configuration says we should. Use this in production.Vitally.nps('show')
- Force displays a survey to users and skips your configuration. Do not use this in production. Only use if you want to test the survey experience AND see the response display in your Vitally account.Vitally.nps('test')
- Force displays a survey to users and skips your configuration. Do not use this in production. Only use if you want to test the survey experience WITHOUT seeing the response in your Vitally account.
If you use Segment to track and send your users and accounts to other tools, Vitally provides a 'shortcut' way to reuse your Segment logic alongside our NPS Javascript.
To do so, you still need to follow most of the steps described here. However, do not worry about identifying the user and account via the
Vitally.user
and Vitally.account
APIs. Instead, when calling Vitally.nps('survey')
, in the second argument that supports additional options, specify an autoLoadSegment
option and set to true
. Vitally.nps('survey', {
productName: 'Pied Piper',
autoLoadSegment: true,
delay: 1000
});
Doing this will listen for calls to Segment's
analytics.identify
and analytics.group
APIs. When detected, the NPS survey will automatically use the user and account tracked via Segment.Putting this all together, an entire example snippet to add to your HTML that uses Segment's user and account would look something like this:
<script type="text/javascript" src="https://cdn.vitally.io/vitally.js/v1/vitally.js" defer></script>
<script type="text/javascript">
!function(n,t,r){for(var i=n[t]=n[t]||[],o=function(r){i[r]=i[r]||function(){for(var n=[],t=0;t<arguments.length;t++)n[t]=arguments[t];return i.push([r,n])}},u=0,c=["init","user","account","track","nps"];u<c.length;u++){o(c[u])}}(window,"Vitally");
Vitally.init('YOUR_TOKEN_HERE');
Vitally.nps('survey', {
productName: 'Pied Piper',
autoLoadSegment: true,
delay: 1000
});
</script>