> ## Documentation Index
> Fetch the complete documentation index at: https://docs.usertour.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Usertour.js Installation

> installation of Usertour.js.

Before your users can see the content you build, you need to install Usertour.js in your web app.

Usertour.js is a tiny piece of JavaScript code (\~20 kB), which is loaded asynchronously in your web app, so it won’t affect your page load speed.

The installation is simple and only requires 2 quick steps:

## Step 1: Install Usertour.js

Usertour.js can be installed in one of 2 ways:

* Browser apps using module bundlers (such as Webpack or Rollup)

  * [Npm installation](#npm-installation)

* Other browser apps and Google Tag Manager

  * [HTML snippet installation](#html-snippet-installation)

### Npm installation

We recommend installing Usertour.js using the [usertour.js npm package](https://www.npmjs.com/package/usertour.js).

First, run this in your Terminal:

```bash theme={null}
npm install usertour.js
```

Import and use the `usertour` object from the `usertour.js` module:

```javascript theme={null}
import usertour from 'usertour.js';

usertour.init('USERTOUR_TOKEN');
usertour.identify('USER_ID', {
  name: 'USER_NAME',
  email: 'USER_EMAIL',
  signed_up_at: 'USER_SIGNED_UP_AT',
});
```

**Important:** Make sure to replace the placeholders with real, dynamic values from your app! See [Step 2](#step-2-replace-placeholders).

### HTML snippet installation

Copy-paste the following snippet into your HTML document before the ending tag:

```html theme={null}
<script>
!function(){var e="undefined"==typeof window?{}:window,r=e.usertour;if(!r){var t="https://js.usertour.io/",n=null;r=e.usertour={_stubbed:!0,load:function(){return n||(n=new Promise((function(r,o){var s=document.createElement("script");s.async=!0;var i=e.USERTOURJS_ENV_VARS||{};"es2020"===(i.USERTOURJS_BROWSER_TARGET||function(e){for(var r=[[/Edg\//,/Edg\/(\d+)/,80],[/OPR\//,/OPR\/(\d+)/,67],[/Chrome\//,/Chrome\/(\d+)/,80],[/CriOS\//,/CriOS\/(\d+)/,100],[/Safari\//,/Version\/(\d+)/,14],[/Firefox\//,/Firefox\/(\d+)/,74]],t=0;t<r.length;t++){var n=r[t],o=n[0],s=n[1],i=n[2];if(e.match(o)){var u=e.match(new RegExp(s));if(u&&parseInt(u[1],10)>=i)return"es2020";break}}return"legacy"}(navigator.userAgent))?(s.type="module",s.src=i.USERTOURJS_ES2020_URL||t+"es2020/usertour.js"):s.src=i.USERTOURJS_LEGACY_URL||t+"legacy/usertour.iife.js",s.onload=function(){r()},s.onerror=function(){document.head.removeChild(s),n=null;var e=new Error("Could not load Usertour.js");console.warn(e.message),o(e)},document.head.appendChild(s)}))),n}};var o=e.USERTOURJS_QUEUE=e.USERTOURJS_QUEUE||[],s=function(e){r[e]=function(){var t=Array.prototype.slice.call(arguments);r.load(),o.push([e,null,t])}},i=function(e){r[e]=function(){var t,n=Array.prototype.slice.call(arguments);r.load();var s=new Promise((function(e,r){t={resolve:e,reject:r}}));return o.push([e,t,n]),s}},u=function(e,t){r[e]=function(){return t}},a=function(e){r[e]=function(){console.warn("usertour.js: "+e+" is not supported and was ignored")}};s("disableEvalJs"),s("init"),s("off"),s("on"),s("registerCustomInput"),s("reset"),s("setBaseZIndex"),s("setTargetMissingSeconds"),s("setCustomNavigate"),s("setCustomScrollIntoView"),s("setUrlFilter"),s("setLinkUrlDecorator"),s("openResourceCenter"),s("closeResourceCenter"),s("toggleResourceCenter"),s("showResourceCenterLauncher"),s("hideResourceCenterLauncher"),a("setCustomInputSelector"),a("setSessionTimeout"),a("setInferenceAttributeFilter"),a("setInferenceAttributeNames"),a("setInferenceClassNameFilter"),a("setScrollPadding"),a("setServerEndpoint"),a("setShadowDomEnabled"),a("setPageTrackingDisabled"),i("endAll"),i("group"),i("identify"),i("identifyAnonymous"),i("start"),i("track"),i("updateGroup"),i("updateUser"),u("isIdentified",!1),u("isResourceCenterOpen",!1),u("isStarted",!1)}}();

  
  usertour.init('USERTOUR_TOKEN');
  usertour.identify('USER_ID', {
    name: 'USER_NAME',
    email: 'USER_EMAIL',
    signed_up_at: 'USER_SIGNED_UP_AT',
  });
</script>
```

**Important:** Make sure to replace the placeholders with real, dynamic values from your app! See [Step 2](#step-2-replace-placeholders).

## Step 2: Replace placeholders

In the code you copy-pasted above, replace **USERTOUR\_TOKEN** with the Usertour.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 usertour.identify()‘s second argument are all optional. They’re useful for looking up users in Usertour 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 Usertour, feel free to leave out the argument completely.

That’s it! Your Usertour installation is ready.

## Optional: Add custom attributes

Usertour.js supports sending custom attributes: Key-value pairs of data such as user role or other preferences. See Usertour.js Reference for how to use attributes.

## Optional: Prove user identities

Your environment token is public, so by default anyone holding it could call usertour.identify() with any user ID. To prevent impersonation, your backend can sign an identity token (a JWT) for each user and pass it as identify()'s third argument. See the [Identity Verification guide](/developers/identity-verification).

## Optional: Install Usertour for uauthenticated users

Running usertour.identify() is a mandatory part of the script. But if you want to show Usertour content on public pages to users who are not yet signed into your application, you can install the script on those pages and replace usertour.identify() with usertour.identifyAnonymous(). With this function Usertour.js will automatically assign the current user a unique ID. But note that they will count as users in the MAU balance.

[See usertour.identifyAnonymous() docs]()
