> For the complete documentation index, see [llms.txt](https://docs.reo.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.reo.dev/install-the-tracking-snippet-with-an-npm-package.md).

# Install the tracking snippet with an NPM package

### Overview

This method adds Reo.dev's tracking script as a code package inside your project, using <mark style="color:red;">`npm`</mark> or <mark style="color:red;">`yarn`</mark> (the tools JavaScript developers use to install and manage packages).

Use this if your website, documentation site, or product is built with a JavaScript framework, like React, Next.js, or Vue, and you or your engineering team manages that code directly.

Reo.dev tracks three types of assets:

* **Website**
* **Documentation**
* **Cloud Product** (your logged-in product)

Each is configured separately in Reo.dev under **Settings → Integrations**. The install code below is the same for all three, with one small difference for Cloud Product [noted in Step 2](https://app.gitbook.com/o/j0dmg4x3Hdhfj3EDr66v/sites/site_LYknN/s/x46P5sAHxDG7PqOdVLxI/~/edit/~/changes/731/install-the-tracking-snippet-with-an-npm-package#step-2-add-the-initialization-code).

#### **Is this the right method for you?**

* This method means editing your project's source code and redeploying it.
* If that's not something you do yourself, share this page with whoever manages your site's or product's codebase.
* Or, use one of the other install methods instead, pasting the script directly, or Google Tag Manager, neither of which touches your codebase.

***

### Step 1: Install the package

In your project's terminal, run:

```bash
npm i reodotdev
# or
yarn add reodotdev
```

This adds Reo's tracking package to your project.

***

### Step 2: Add the initialization code

1. **Integrate the package into your project:** Identify the file or module in your project where you want to add tracking, typically the root file that loads your entire application, for example <mark style="color:red;">`_app.js`</mark>, <mark style="color:red;">`layout.tsx`</mark>, or a similar entry point. <br>
2. **Import and load the tracking script:** Import the required function from the package you installed, then use it to load Reo.dev's tracking script.<br>
3. Add the code below to that file:

```javascript
  // Use with NPM
import { loadReoScript } from 'reodotdev'

// Declare clientID from environment variable or directly as string
const clientID = process.env.CLIENT_ID || "XXXXXXXXXX";

// Resolve promise to get access to methods on Reo
const reoPromise = loadReoScript({ clientID });
reoPromise
  .then(Reo => {
     Reo.init({ clientID });
  })
  .catch(error => {
    console.error('Error loading Reo', error);
  })
```

4. This code looks for a <mark style="color:red;">`CLIENT_ID`</mark> environment variable first, and falls back to the literal string <mark style="color:red;">`"XXXXXXXXXX"`</mark> if none is set.
   1. Replace <mark style="color:red;">`"XXXXXXXXXX"`</mark> directly with your Client ID.&#x20;
   2. Set <mark style="color:red;">`CLIENT_ID`</mark> as an environment variable in your project, using that same Client ID as its value.
   3. **On a side note** - adjust environment variables if needed: If you're using environment variables, make sure to set them up in your environment configuration or <mark style="color:red;">`.env`</mark> files.

{% hint style="info" %}
**Note:** This same code works for tracking your Website or Documentation, just use the Client ID from your Reo.dev workspace.&#x20;
{% endhint %}

#### **If you are setting up Cloud Product tracking instead, read this:**&#x20;

* The code above includes a <mark style="color:red;">`.catch()`</mark> block - the part starting with <mark style="color:red;">`.catch(error => {...})`</mark>.
* It only runs if the script fails to load, and its job is to print a message so you'd notice.
* We'd recommend keeping it in your code: without it, a failed load happens silently, with no error and no message telling you it didn't work.

***

### Step 3: Save, build, and deploy

* Save the file containing the updated code.&#x20;
* Compile or bundle your project according to your build process, then deploy the changes to your server or hosting service.
* The tracking script activates once your updated site or product is live.

***

### Verify it worked

The fastest way: on the relevant configuration page (Documentation, Website or Cloud Product) in Reo.dev (**Settings → Integrations**), click **Check status** in the top-right corner. It tells you whether Reo.dev is receiving data.

To check manually instead:

1. Open your site
   1. For Cloud Product tracking, log in first, since that's where the tracked screens live
2. Right-click anywhere on the page and select **Inspect**
3. In the Network tab, search for <mark style="color:red;">`reo`</mark> and check if the network calls are being registered (status code: 200)

***

### Advanced: identify logged-in users

**If your product has a login, calling&#x20;**<mark style="color:red;">**`identify`**</mark>**&#x20;is an essential step.**&#x20;

* Sign-in flows vary, some are built in-house, some use a third-party provider, some use an IDP (identity provider), so Reo.dev has no way to automatically detect a successful sign-in.
* That's why it exposes <mark style="color:red;">`identify`</mark> as a method you call yourself, right after a successful sign-in, with the person's details as its payload.&#x20;
* This tells Reo.dev who the user is and that they've logged in, attaching their activity to a real identity instead of leaving it anonymous.
* <mark style="color:red;">`identify`</mark> only works after Reo.dev has finished loading, so call it after <mark style="color:red;">`Reo.init`</mark> ([from Step 2](https://app.gitbook.com/o/j0dmg4x3Hdhfj3EDr66v/sites/site_LYknN/s/x46P5sAHxDG7PqOdVLxI/~/edit/~/changes/731/install-the-tracking-snippet-with-an-npm-package#step-2-add-the-initialization-code)), not before. The <mark style="color:red;">`Reo &&`</mark> check below confirms Reo.dev has finished loading before <mark style="color:red;">`identify`</mark> runs, so this doesn't error out if your sign-in callback fires too early.

```javascript
  const identity = {
      "username": "johndoe@microsoft.com",
      "type": "email", // primary identifier to be email
      "other_identities": [
        {
          "username": "johndoe83",
          "type": "github" // other identifiers can be github, linkedin
        }
      ],
      "firstname": "John",
      "lastname": "Doe",
      "company": "microsoft.com" // company domain
    }
    Reo && Reo.identify(identity);
```

The <mark style="color:red;">`Reo &&`</mark> check simply confirms Reo.dev has finished loading before calling <mark style="color:red;">`identify`</mark>, so this doesn't error out if it runs too early.

* <mark style="color:red;">`username`</mark> and <mark style="color:red;">`type`</mark> are required: the person's identifier, and what kind of identifier it is (<mark style="color:red;">`email`</mark>, <mark style="color:red;">`github`</mark>, or <mark style="color:red;">`linkedin`</mark>). <mark style="color:red;">`type`</mark> describes the format of the username itself, not how the person signed in. For example, someone can sign in with GitHub but still be identified by their email address, in which case <mark style="color:red;">`username`</mark> would be their email and <mark style="color:red;">`type`</mark> would be <mark style="color:red;">`"email"`</mark><mark style="color:red;">.</mark>
* <mark style="color:red;">`other_identities`</mark> is optional: any other identifiers for the same person, for example their email if they signed in with GitHub
* <mark style="color:red;">`firstname`</mark>, <mark style="color:red;">`lastname`</mark>, and <mark style="color:red;">`company`</mark> are optional, and enrich their profile with extra detail

***

### Advanced: copy tracking, and how to turn it off

By default, Reo.dev also tracks when someone copies a command or code snippet from your page.&#x20;

**This is a useful signal: someone copying your install command is likely about to try your product.**&#x20;

For logged-in users on your Cloud Product, like free or trial users, this also flags high-intent activity: copying a code block or running a CLI command is a strong proxy for how far along they are in evaluating your product.

If you'd rather turn copy tracking off entirely, add the <mark style="color:red;">`dnt`</mark> (do not track) flag when you initialize Reo.dev:

```javascript
reoPromise
  .then(Reo => {
    Reo.init({ clientID, dnt: ["copy"] });
  });
```

***

### Error scenarios

#### **1. The script doesn't load**

The tracking snippet only runs after it downloads successfully from Reo.dev's Content Delivery Network (CDN), the servers that host the script file. A failed download doesn't break your page. It just means that visit isn't tracked.

This also won't throw visible errors in your browser's console. That's intentional: the script has built-in error handling so a tracking hiccup never clutters your production logs. If your site enforces a Content Security Policy, an unlisted domain can also cause this same silent failure, see CSP requirements below.

#### **2. A tracking event occasionally fails to send**

In rare cases, Reo.dev resets its internal authentication behind the scenes. If that happens while an event is sending, that one event may not go through, but this resolves on its own and later events send normally. No action is needed.

#### **3. Avoid duplicate installs**

Don't initialize Reo.dev more than once in the same project. Multiple copies can conflict with each other.

{% hint style="info" %}
Still stuck? Contact your Customer Success Manager on Slack, or email [**support@reo.dev**](mailto:support@reo.dev).
{% endhint %}

***

### CSP requirements

If your site enforces a Content Security Policy (CSP), allow these domains. This is usually set in your site's HTTP response headers or a CSP meta tag, ask whoever manages your hosting if you're not sure where.

* <mark style="color:red;">`script-src <https://static.reo.dev>`</mark>
* <mark style="color:red;">`connect-src <https://api.reo.dev>`</mark>

For cookies and data handling, see the [cookie management guide](https://docs.reo.dev/reo.dev-javascript-cookies-and-consent-guide).

***

### FAQs

{% hint style="info" %}
For questions about the tracking script itself, safety, performance, PII, browser support, and compliance, check out the FAQ on the [Website integration guide](https://docs.reo.dev/integrations/input-sources/developer-insights/website) or [Documentation integration guide](https://docs.reo.dev/integrations/input-sources/developer-insights/documentation). Those apply for installation with NPM package as well.
{% endhint %}

* **Do I need to set the&#x20;**<mark style="color:red;">**`CLIENT_ID`**</mark>**&#x20;environment variable, or can I hardcode it?**\
  Either works. The environment variable in [Step 2](https://app.gitbook.com/o/j0dmg4x3Hdhfj3EDr66v/sites/site_LYknN/s/x46P5sAHxDG7PqOdVLxI/~/edit/~/changes/731/install-the-tracking-snippet-with-an-npm-package#step-2-add-the-initialization-code) is just a convention, so you're not hardcoding config values into your source code, but the Client ID itself isn't sensitive, so pasting it directly as a string works fine too.<br>
* **Should I add a&#x20;**<mark style="color:red;">**`.catch()`**</mark>**&#x20;block for Cloud Product tracking?**\
  Yes, we recommend it. It only runs if the script fails to load, and its job is to print a message so you'd notice. [See Step 2](https://app.gitbook.com/o/j0dmg4x3Hdhfj3EDr66v/sites/site_LYknN/s/x46P5sAHxDG7PqOdVLxI/~/edit/~/changes/731/install-the-tracking-snippet-with-an-npm-package#step-2-add-the-initialization-code) for the full code and explanation.<br>
* **What happens if I don't call&#x20;**<mark style="color:red;">**`identify()`**</mark>**?**\
  Nothing breaks. Tracking still works, the session just stays anonymous instead of being linked to a known person.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.reo.dev/install-the-tracking-snippet-with-an-npm-package.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
