ForgeRock Developer Experience

Set up device profiling in JavaScript apps

This page shows how to detect the DeviceProfileCallback, how to collect the device profile, and how to send the profile to your server.

The server includes collected device information in its audit logs by default.

To configure AM to filter out this information and ensure no personally identifiable information (PII) is written to the audit logs, refer to Prevent auditing of device data.

Handle a device profile callback

  1. Get the callback and any messages to display to the user:

    const deviceCollectorCb = step.getCallbackOfType('DeviceProfileCallback');
    const message = deviceCollectorCb.getMessage();
  2. From the callback, determine if the intention is to collect the device location, the device metadata, or both:

    const isLocationRequired = deviceCollectorCb.isLocationRequired();
    const isMetadataRequired = deviceCollectorCb.isMetadataRequired();
  3. Create a new instance of the FRDevice class.

    const device = new forgerock.FRDevice();

    To return specific device data, pass in configuration options to the FRDevice constructor. For example, you can return device platform, display, browser, and hardware data.

Manually collect device profile information

Instead of responding to a device callback, your app can get the device profile using default collectors.

  1. Call the getProfile() method of the FRDevice class, passing the boolean values from the callback that indicate if device location and/or device metadata is required:

    const profile = await device.getProfile({
     location: isLocationRequired,
     metadata: isMetadataRequired,
    To return specific device data, override the FRDevice class methods for getting the device metadata, device browser plugins, device name, device hardware, and so on.
  2. Set the device profile information for the step:


Default collectors

Collector name Description


Collect font information.


Collect display information of the device.


Collect browser information of the device.


Collect hardware related information.


Collect platform related information

Sample device profile

  "identifier": "714524572-2799534390-3707617532",
  "metadata": {
    "hardware": {
      "cpuClass": null,
      "deviceMemory": 8,
      "hardwareConcurrency": 16,
      "maxTouchPoints": 0,
      "oscpu": null,
      "display": {
        "width": 1080,
        "height": 1920,
        "pixelDepth": 24,
        "angle": 270
    "browser": {
      "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36 Edg/80.0.361.111",
      "appName": "Netscape",
      "appCodeName": "Mozilla",
      "appVersion": "5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36 Edg/80.0.361.111",
      "appMinorVersion": null,
      "buildID": null,
      "product": "Gecko",
      "productSub": "20030107",
      "vendor": "Google Inc.",
      "vendorSub": "",
      "browserLanguage": null,
      "plugins": "internal-pdf-viewer;mhjfbmdgcfjbbpaeojofohoefgiehjai;internal-nacl-plugin;"
    "platform": {
      "deviceName": "Mac (Browser)"
      "language": "en-US",
      "platform": "MacIntel",
      "userLanguage": null,
      "systemLanguage": null,
      "fonts": "cursive;monospace;sans-serif;fantasy;Arial;Arial Black;Arial Narrow;Arial Rounded MT Bold;Comic Sans MS;Courier;Courier New;Georgia;Impact;Papyrus;Tahoma;Trebuchet MS;Verdana;",
      "timezone": 300
  "location": {
    "latitude": 30.49843,
    "longitude": -97.639371

Create a custom collector

  1. Create an instance of FRDevice and customize the profile:

    const device = new FRDevice({
      // Example customization:
      // Collect just the presence of Arial and Helvetica
      fontNames: [ 'Arial', 'Helvetica' ],
      // Do not collect any display properties
      displayProps: [],
      // Just collect User Agent
      browserProps: [ 'userAgent' ]
  2. Replace the methods for further customization:

    device.getHardwareMeta = function () {
      let obj;
      // Custom logic to collect hardware profile obj
      return obj;
  3. Run the getProfile() method using the custom configuration and collector methods:

    const profile = await device.getProfile({
      location: isLocationRequired,
      metadata: isMetadataRequired,

Device profile attributes

By default, the ForgeRock SDk collects the following device attributes:

Attribute Value


A unique ID for the device.

To learn more about the device identifier, refer to Uniquely identifying devices.


The location of a device (longitude and latitude values).

This is configured in the node and requires user permissions.


Metadata for the device, including:


The device OS, such as Android or iOS.


The name of the device.


The locale of the device, such as en.


The time zone of the device, such as Africa/Johannesburg.


The brand of the device, such as Apple.


A value between 0.0 and 1.0 that denotes the tampering level for a device.

Obtain user permission for the device location

Your app requires the user’s authorization to access the device location.

If the user denies location access, the SDK still collects the device profile data; however, the collected data will not include any location coordinates.

If the user provides the permission, the SDK collects the location coordinates.

Known limitations

  • Location access requires user permissions. If the user denies permission or doesn’t respond to the browser’s request in time, geolocation coordinates are not collected and the profile is generated without it.

  • Generating the profile can take time, especially when the location is requested. If this is a step all to itself, showing a spinner with message is recommended.

  • To reduce authentication round-trips/latency, you can collect the device profile at the same time you collect other information.

  • The device profile ID is generated if one doesn’t exist, and stored in the browser’s localStorage. If this is done within a browser’s "private" or "incognito" mode, the ID does not persist once that window is closed. This creates a new ID, and therefore a new profile, when the profile is generated again.

  • As JavaScript runs within a browser, it is more a browser profile than a device profile. A different browser on the same device produces a substantially different profile.

  • Some profile attributes are more volatile than others. Plugging an external display into a laptop, for example, alters the generated profile.

More information

Copyright © 2010-2024 ForgeRock, all rights reserved.