Before your users can see the flows and other content you build, you need to install Userflow.js in your web app.
Userflow.js is a small piece of JavaScript that loads asynchronously in your web app, so it won’t slow down your page load.
Install with your AI coding agent
Let your AI coding agent do the work. Pick the skill that matches where you are:
Install with AI Verify with AI Suggest with AI
All three are added to your agent the same way—see Add Userflow coding skills to your agent. Prefer to install by hand? Follow the steps below.
The installation is simple and only requires 3 quick steps:
With several optional steps:
Step 1: Choose installation method
Userflow.js can be installed in one of 2 ways:
Browser apps using module bundlers (such as Webpack or Rollup)
Other browser apps and Google Tag Manager
We also have specific instructions for special apps/tools:
Self-hosted Userflow.js (not recommended). Contact support first, because a self-hosted setup has to be reviewed by Userflow engineering.
Step 2A: npm installation
We recommend installing Userflow.js using the userflow.js npm package.
First, run this in your Terminal:
npm install userflow.jsImport and use the userflow object from the userflow.js module:
import userflow from 'userflow.js'
userflow.init('USERFLOW_TOKEN')
userflow.identify('USER_ID', {
name: 'USER_NAME',
email: 'USER_EMAIL',
signed_up_at: 'USER_SIGNED_UP_AT'
})Important: Replace the placeholders in the code (USERFLOW_TOKEN, USER_ID, USER_NAME, USER_EMAIL, and USER_SIGNED_UP_AT) with real values from your app. See Step 3: Replace placeholders.
Step 2B: HTML snippet installation
Only do this if you did not complete Step 2A.
Copy-paste the following snippet into your HTML document before the ending </body> tag:
<script>
!function(){var e="undefined"==typeof window?{}:window,t=e.userflow,r=e.history;function n(t,n){return function(){var o=new CustomEvent(n),s=Array.prototype.slice.call(arguments),a=t.apply(r,s);return e.dispatchEvent(o),a}}if(r){e.__userflowStatePatched=!0;var o=r.pushState,s=r.replaceState;r.pushState=n(o,"userflow:pushstate"),r.replaceState=n(s,"userflow:replacestate")}if(!t){var a="https://js.userflow.com/",l=null;t=e.userflow={_stubbed:!0,load:function(){return l||(l=new Promise((function(t,r){var n=document.createElement("script");n.async=!0;var o=e.USERFLOWJS_ENV_VARS||{};"es2020"===(o.USERFLOWJS_BROWSER_TARGET||function(e){for(var t=[[/Edg\//,/Edg\/(\d+)/,80],[/OPR\//,/OPR\/(\d+)/,67],[/Chrome\//,/Chrome\/(\d+)/,80],[/CriOS\//,/CriOS\/(\d+)/,100],[/Safari\//,/Version\/(\d+)/,14],[/Firefox\//,/Firefox\/(\d+)/,74]],r=0;r<t.length;r++){var n=t[r],o=n[0],s=n[1],a=n[2];if(e.match(o)){var l=e.match(new RegExp(s));if(l&&parseInt(l[1],10)>=a)return"es2020";break}}return"legacy"}(navigator.userAgent))?(n.type="module",n.src=o.USERFLOWJS_ES2020_URL||a+"es2020/userflow.js"):n.src=o.USERFLOWJS_LEGACY_URL||a+"legacy/userflow.js",n.onload=function(){t()},n.onerror=function(){document.head.removeChild(n),l=null;var e=new Error("Could not load Userflow.js");console.warn(e.message),r(e)},document.head.appendChild(n)}))),l}};var u=e.USERFLOWJS_QUEUE=e.USERFLOWJS_QUEUE||[],i=function(e){t[e]=function(){var r=Array.prototype.slice.call(arguments);t.load(),u.push([e,null,r])}},c=function(e){t[e]=function(){var r,n=Array.prototype.slice.call(arguments);t.load();var o=new Promise((function(e,t){r={resolve:e,reject:t}}));return u.push([e,r,n]),o}},d=function(e,r){t[e]=function(){return r}};i("_setTargetEnv"),i("closeResourceCenter"),i("disableEvalJs"),i("init"),i("off"),i("on"),i("prepareAudio"),i("registerCustomInput"),i("remount"),i("reset"),i("setBaseZIndex"),i("setCustomInputSelector"),i("setCustomNavigate"),i("setCustomScrollIntoView"),i("setInferenceAttributeFilter"),i("setInferenceAttributeNames"),i("setInferenceClassNameFilter"),i("setResourceCenterLauncherHidden"),i("setScrollPadding"),i("setServerEndpoint"),i("setShadowDomEnabled"),i("setPageTrackingDisabled"),i("setUrlFilter"),i("setLinkUrlDecorator"),i("openResourceCenter"),i("toggleResourceCenter"),c("endAll"),c("endAllFlows"),c("endChecklist"),c("group"),c("identify"),c("identifyAnonymous"),c("start"),c("startFlow"),c("startWalk"),c("track"),c("updateGroup"),c("updateUser"),c("debugger"),d("getResourceCenterState",null),d("isIdentified",!1)}}();
userflow.init('USERFLOW_TOKEN')
userflow.identify('USER_ID', {
name: 'USER_NAME',
email: 'USER_EMAIL',
signed_up_at: 'USER_SIGNED_UP_AT'
})
</script>Important: Replace the placeholders in the code (USERFLOW_TOKEN, USER_ID, USER_NAME, USER_EMAIL, and USER_SIGNED_UP_AT) with real values from your app. See Step 3: Replace placeholders.
Step 3: Replace placeholders
In the Userflow.js code from Step 2A or Step 2B, replace USERFLOW_TOKEN with the Userflow.js Token you find under Settings > Environments. Note that if you have multiple environments (e.g. Production and Staging) that each environment has a unique token.
Next, replace USER_ID with the currently signed in user’s ID in your database. Also replace USER_NAME, USER_EMAIL and USER_SIGNED_UP_AT with the user’s real, dynamic values. signed_up_at should be specified in ISO 8601 format. Example: 2019-12-11T12:34:56Z.
The properties in userflow.identify()‘s second argument are all optional. They’re useful for looking up users in Userflow to e.g. see their flow progress, or to use in the flow content or conditions. If you don’t want to share this with Userflow, feel free to leave out the argument completely.
That’s it! Your Userflow installation is ready.
Optional: Add custom attributes
Userflow.js supports sending custom attributes: Key-value pairs of data such as user role or other preferences. See Userflow.js Reference for how to use attributes.
Optional: Enforce identity verification
Identity verification is a Userflow security feature that prevents malicious third parties from impersonating your users.
We strongly recommend that you configure and enforce identity verification to safe-guard your users’ information.
See the identity verification guide
Optional: Install Userflow for unauthenticated users
Running userflow.identify() is a mandatory part of the script. But if you want to show Userflow content on public pages to users who are not yet signed into your application, you can install the script on those pages and replace userflow.identify() with userflow.identifyAnonymous(). With this function Userflow.js will automatically assign the current user a unique ID. But note that they will count as users in the MAU balance.
When a User ID is created for an anonymous end user, it is unique and is also stored in local storage. When userflow.identifyAnonymous() is called during subsequent activity by the user, we reuse the already stored anonymous User ID from local storage.
The ID stays in local storage until it's cleared. Userflow.js doesn't set cookies for this.
See userflow.identifyAnonymous() docs
Optional: Wait for cookie consent
If your app asks users for cookie consent, don't call userflow.init() or userflow.identify() until they agree, and call userflow.reset() if they withdraw it. Userflow.js has no built-in consent setting.
For what Userflow stores in the browser and which consent category to use, see Cookies, browser storage, and consent.