Migrating from previous versions

From FingerprintJS Pro version 2

The JS agent has several changes compared to the previous version. Server API, webhooks and other integrations have not changed.

Browser support

Internet Explorer 10 is no longer supported in v3. Some old browsers like Internet Explorer 11 and Android Browser 4.1 require a Promise polyfill. See the browser support guide to get a list of the supported browsers and learn how to use FingerprintJS Pro in old browsers.

Installation

CDN

Skip this section if you installed the v2 of the JS agent via NPM.
The cdn.fpjs.io is no longer support, use cdn.jsdelivr.net instead.
Here is the new CDN URL: https://cdn.jsdelivr.net/npm/@fingerprintjs/[email protected]/dist/fp.min.js.

The global variables fp and fpLayer were replaced with FingerprintJS which provides the same API as the NPM version. Instead of passing configuration parameters to fp('config', ...), you should pass them to FingerprintJS.load({ ... }).
Example before:

<head>
  <script>
    window.fpLayer = window.fpLayer || [];
    function fp() { fpLayer.push(arguments); }
    fp('config', 'client', 'your-token');
    fp('config', 'endpoint', 'your-endpoint'); // If you have a subdomain integration
    fp('config', 'loaded', function (fpAgent) {
      // Your code that uses the agent
      fpAgent.send()
    });
  </script>
  <script async src="https://cdn.fpjs.io/@2/fp.js"></script>
</head>

Example after:

<head>
  <script>
    // Initialize the agent at application startup.
    const fpPromise = new Promise((resolve, reject) => {
      const script = document.createElement('script');
      script.onload = resolve;
      script.onerror = reject;
      script.async = true;
      script.src = 'https://cdn.jsdelivr.net/npm/'
        + '@fingerprintjs/fingerpr[email protected]/dist/fp.min.js';
      document.head.appendChild(script);
    })
        .then(() => FingerprintJS.load({
        token: 'your-token',
        endpoint: 'your-endpoint' // If you have a subdomain integration
      }));

    // Get the visitor identifier when you need it.
    fpPromise.then(fpAgent => {
      // Your code that uses the agent
      fpAgent.get()
    })
  </script>
</head>

NPM

Skip this section if you installed the v2 of the JavaScript agent via CDN. Replace the old NPM package with the new one:

npm remove @fp-pro/client
npm install @fingerprintjs/fingerprintjs-pro
yarn remove @fp-pro/client
yarn add @fingerprintjs/fingerprintjs-pro

Then update the import code. Change the package name and import FP as a default export. Example:

- import { FP } from '@fp-pro/client'
+ import FP from '@fingerprintjs/fingerprintjs-pro'

The exported constants are available as default export properties and as individual exports:

import FP, { ERROR_CLIENT_TIMEOUT } from '@fingerprintjs/fingerprintjs-pro'
FP.ERROR_CLIENT_TIMEOUT // Also works

Configuration

This section describes what was changed in the configuration parameters that are passed to the FP.load() method or to fp('config', ...).

client

Rename the client parameter to token.

const fp = await FP.load({
- client: 'your-token'
+ token: 'your-token'
})

region

In v3, the parameter is optional for NPM, so you can remove region: 'us'.

cookieDomain

Remove this parameter, it is not used anymore. The best cookie domain is detected automatically.

autoSend

The parameter is removed. Send explicitly when the agent loads. Call fp.get() right after the agent loads:

<script>
  new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.onload = resolve;
    script.onerror = reject;
    script.async = true;
    script.src = 'https://cdn.jsdelivr.net/npm/'
      + '@fingerprintjs/[email protected]/dist/fp.min.js';
    document.head.appendChild(script);
  })
    .then(() => FingerprintJS.load({ token: 'your-token' }))
      .then(fp => fp.get()); // Automatic sending when the agent is ready
</script>

loaded

The parameter is removed. Put your "loaded" handling code right after the agent loads.

<script>
  // Initialize the agent at application startup.
  const fpPromise = new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.onload = resolve;
    script.onerror = reject;
    script.async = true;
    script.src = 'https://cdn.jsdelivr.net/npm/'
      + '@fingerprintjs/[email protected]/dist/fp.min.js';
    document.head.appendChild(script);
  })
    .then(() => FingerprintJS.load({ token: 'your-token' }));

  fpPromise.then(fp => {
    // Put the code that handles "loaded" event here
  })
</script>

cookieKey

Rename the parameter to storageKey. It affects local storage too.

timeoutDelay

Rename the parameter to delayFallback.

Sending data

Rename the .send() method to .get().

const fp = await FP.load()
- await fp.send(options)
+ await fp.get(options)

callbackData

Rename the parameter to extendedResult.

await fp.get({
- callbackData: true
+ extendedResult: true
})

ip

Remove the parameter because it is not supported.

await fp.get({
- ip: 'city'
})

Receiving data

Some results that were resolved in v2 are rejected in v3 and vice-versa. The shift has been done to simplify resolved and rejected value types. See the expected errors table to learn the cases that lead to errors. Generally speaking, error are thrown only when your attention is required.

The .get() method returns a promise that is resolved with an object of a single predictable format. The format is similar to the visitor data format from v2. The differences are described below.

visitorId

If a visitor can't be identified, the visitorId field value is an empty string instead of 'n/a'. The rest of the result object will have the same type (as for an identified visitor) in this case.

- import { NotAvailable } from '@fp-pro/client'
- if (result.visitorId === NotAvailable) {
+ if (!result.visitorId) {
    console.log('The visitor can not be identified')
  }

tag

The tag field was removed from the .get() method’s response for simplicity. Previously, this value was sent and received without ever changing.

const optionsTag = { userId: 123, coupon: 'FOOBAR' }
const result = await fp.get({ tag: optionsTag })
- const resultTag = result.tag
+ const resultTag = optionsTag

botProbability

The property is replaced with the bot field that has the probability subfield.

// Visitor data example:
  {
    visitorId: 'qwerty12345',
-   botProbability: 1,
+   bot: {
+     probability: 1
+   },
    // ...
  }

When the visitor isn't suspected to be a bot, the bot field is undefined.

The bot detection feature of JS agent is deprecated, we're working on a new product for bot detection. Please contact support for more details.

Error handling

The JavaScript agent .get() method returns a promise which will be rejected in the case of an error. The JavaScript agent provides constants for every expected error. To see a list of common error messages, click here.

<script>
  new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.onload = resolve;
    script.onerror = reject;
    script.async = true;
    script.src = 'https://cdn.jsdelivr.net/npm/'
      + '@fingerprintjs/[email protected]/dist/fp.min.js';
    document.head.appendChild(script);
  }).then(() => {
    FingerprintJS.ERROR_CLIENT_TIMEOUT;
    FingerprintJS.ERROR_NETWORK_CONNECTION;
    // And many more
  });
</script>
import FingerprintJS from '@fingerprintjs/fingerprintjs-pro'
// or
import * as FingerprintJS from '@fingerprintjs/fingerprintjs-pro'

FingerprintJS.ERROR_CLIENT_TIMEOUT
FingerprintJS.ERROR_NETWORK_CONNECTION
// And many more

When you catch an error, check the message:

try {
  await fp.get()
} catch (error) {
  if (error.message === FingerprintJS.ERROR_CLIENT_TIMEOUT) {
    // ...
  }
  // ...
}

Search bots

In v2 the .send() method promise was rejected in case of a search bot. In v3 the promise is resolved with a full featured result object. Also the result has the bot.safe field equal to true. Change your search bot checking code:

- try {
-   const result = await fp.get()
+   const result = await fp.get({ extendedResult: true })
- } catch (error) {
-   if (error.reason === 'Not available for crawl bots') {
+   if (!result.visitorId && result.bot && result.bot.safe) {
      console.log("It's a crawl bot")
    }
- }

Missing User-Agent header

V3 rejects the .send() method promise when a visitor accesses a site without a user-agent header because a missing user-agent header is a strong sign of a bot.

For users already using FingerprintJS Pro version 3

Because FingerprintJS Pro follows Semantic Versioning, no code changes are necessary when upgrading from version 3.X.X to the latest version of 3. You only need to increase the JS agent package version as specified in your code.

Please see the changelog to learn about the latest features.

CDN and UMD

This section is for installing JS agent without the use of NPM or Yarn.

If your JS agent installation only uses the major release number, then no action is required — you’ll get the newest version automatically.

The following is an example of a JS agent installation set for auto-updating:

<script>
  const script = document.createElement('script');
  script.src = 'https://cdn.jsdelivr.net/npm/'
    + '@fingerprintjs/[email protected]/dist/fp.min.js';
  // ...
</script>
<script src="https://cdn.jsdelivr.net/npm/@fingerprintjs/[email protected]/dist/fp.min.js"></script>
require(
  ['https://cdn.jsdelivr.net/npm/@fingerprintjs/[email protected]/dist/fp.umd.min.js'],
  (FingerprintJS) => {
    // ...
  },
)

If you've set a minor or a patch version in the URL, your JS agent installation will NOT be updated automatically.

To set it to auto-update, change the entire version number value to just 3, like so:

<script>
  const script = document.createElement('script');
  script.src = 'https://cdn.jsdelivr.net/npm/' +
-   '@fingerprintjs/[email protected]/dist/fp.min.js';
+   '@fingerprintjs/[email protected]/dist/fp.min.js';
  // ...
</script>
- <script src="https://cdn.jsdelivr.net/npm/@fingerprintjs/[email protected]/dist/fp.min.js"></script>
+ <script src="https://cdn.jsdelivr.net/npm/@fingerprintjs/[email protected]/dist/fp.min.js"></script>
require(
- ['https://cdn.jsdelivr.net/npm/@fingerprintjs/[email protected]/dist/fp.umd.min.js'],
+ ['https://cdn.jsdelivr.net/npm/@fingerprintjs/[email protected]/dist/fp.umd.min.js'],
  (FingerprintJS) => {
    // ...
  },
)

ECMAScript and CommonJS

This section is for using NPM or Yarn to install JS agent.

To install the latest version of JS agent, run the following command in a terminal:

npm install @fingerprintjs/fingerprintjs-pro
yarn add @fingerprintjs/fingerprintjs-pro

From FingerprintJS Open-Source version 3

How to migrate from Fingerprintjs Open-Source to FingerprintJS Pro in 30 seconds:

  1. Sign up on dashboard.fingerprintjs.com/signup, create a free subscription, then get a browser token.

  2. Change the @fingerprintjs/fingerprintjs package to @fingerprintjs/fingerprintjs-pro:

    Run:
    npm remove @fingerprintjs/fingerprintjs
    npm install @fingerprintjs/fingerprintjs-pro
    
    And replace the package name in your JavaScript/TypeScript code:
    - import FingerprintJS from '@fingerprintjs/fingerprintjs'
    + import FingerprintJS from '@fingerprintjs/fingerprintjs-pro'
    
    Run:
    yarn remove @fingerprintjs/fingerprintjs
    yarn add @fingerprintjs/fingerprintjs-pro
    
    And replace the package name in your JavaScript/TypeScript code:
    - import FingerprintJS from '@fingerprintjs/fingerprintjs'
    + import FingerprintJS from '@fingerprintjs/fingerprintjs-pro'
    
    Change the script URL:
      <script>
    -   const fpPromise = import('https://openfpcdn.io/fingerprintjs/v3')
    +   const fpPromise = import('https://cdn.jsdelivr.net/npm/@fingerprintjs/[email protected]/+esm')
          .then(FingerprintJS => FingerprintJS.load())
    
        // ...
      </script>
    
    Change the script URL:
      <script>
        // Initialize the agent at application startup.
        const fpPromise = new Promise((resolve, reject) => {
          const script = document.createElement('script');
          script.onload = resolve;
          script.onerror = reject;
          script.async = true;
    -     script.src = 'https://openfpcdn.io/fingerprintjs/v3/iife.min.js';
    +     script.src = 'https://cdn.jsdelivr.net/npm/@fingerprintjs/[email protected]/dist/fp.min.js';
          document.head.appendChild(script);
        })
          .then(() => FingerprintJS.load());
    
        // ...
      </script>
    
    Change the script URL:
    - <script src="https://openfpcdn.io/fingerprintjs/v3/iife.min.js"></script>
    + <script src="https://cdn.jsdelivr.net/npm/@fingerprintjs/[email protected]/dist/fp.min.js"></script>
      <script>
        // ...
      </script>
    
  3. Add the browser token to the FingerprintJS.load() configuration:

    - FingerprintJS.load()
    + FingerprintJS.load({ token: 'your-browser-token' })
    

That's it, the visitorId has pro-level accuracy of 99.5% now.

From FingerprintJS Open-Source version 2

How to migrate from Fingerprintjs Open-Source v2 to FingerprintJS Pro:

  1. Sign up on dashboard.fingerprintjs.com/signup, create a free subscription and get a browser token.

  2. Change the @fingerprintjs/fingerprintjs or fingerprintjs2 package to @fingerprintjs/fingerprintjs-pro. If you use NPM, run:

    npm remove @fingerprintjs/fingerprintjs fingerprintjs2 @types/fingerprintjs__fingerprintjs @types/fingerprintjs2
    npm install @fingerprintjs/fingerprintjs-pro
    
    # Don't mind the "This module isn't specified in a package.json file" error
    yarn remove @fingerprintjs/fingerprintjs fingerprintjs2 @types/fingerprintjs__fingerprintjs @types/fingerprintjs2
    yarn add @fingerprintjs/fingerprintjs-pro
    

    And replace the package name in your JavaScript/TypeScript code:

    - import Fingerprint2 from '@fingerprintjs/fingerprintjs'
    - import Fingerprint2 from 'fingerprintjs2'
    + import FingerprintJS from '@fingerprintjs/fingerprintjs-pro'
    

    If you use a CDN, replace the package name in the script URL.

  3. Replace requestIdleCallback with FingerprintJS.load. The function will return a promise that resolves with an agent object. The agent has a get method that you will use instead of calling Fingerprint2.get directly:

    - requestIdleCallback(() => {
    -   Fingerprint2.get(result => {
    + const fpPromise = FingerprintJS.load()
    + fpPromise
    +   .then(fp => fp.get()){
    +   .then(result => {
          // Handle the result
        })
    - })
    
  4. Add the browser token to the FingerprintJS.load() call:

    - FingerprintJS.load()
    + FingerprintJS.load({ token: 'your-browser-token' })
    
  5. Use the visitor identifier directly (the raw components aren't provided):

      fp.get().then(result => {
    -   const values = result.map(function (component) { return component.value })
    -   const visitorId = Fingerprint2.x64hash128(values.join(''), 31)
    +   const visitorId = result.visitorId
      })
    
  6. Remember that the support of Internet Explorer 10 and older has been dropped. Some old browsers like Internet Explorer 11 and Android Browser 4.1 require a Promise polyfill. See the browser support guide to get a list of the supported browsers and learn how to use FingerprintJS Pro in old browsers.


Did this page help you?