ScientiaMobile WURFL.js Basic/Standard/Pro Getting Started Guide

Introduction

WURFL.js provides access to ScientiaMobile's cloud-based WURFL Device Description Repository (DDR). With a single JavaScript snippet, developers can detect a device and its capabilities in order to better control, optimize, and track the success of their website.

Quick Start

Once you have signed up for a WURFL.js Basic, Standard, or Pro account, you will simply need to enter the hostnames of the websites from which you intend to use WURFL.js:

Customer Vault WURFL.js

If you do not want to configure a CNAME record for your account, then you can now include the following script referencing wjs.wurflcloud.com/wurfl.js in your markup:

<script src="https://wjs.wurflcloud.com/wurfl.js"></script>

For the best detection experience, we recommend loading WURFL.js via the async method, as detailed in the Async loading section below.

The WURFL object is now available to use:

/**
 * Example of pushing WURFL capabilities to google analytics
 */
ga('send', 'pageview', {
    'dimension1': WURFL.complete_device_name,
    'dimension2': WURFL.form_factor,
    'dimension3': WURFL.is_mobile,
    'dimension4': WURFL.is_robot
})

Async loading

WURFL.js dispatches an event called WurflJSDetectionComplete to the document node when it's finished. This allows you to include it in async mode and avoid DOM-blocking content. We do not recommend that the script tag be placed in the document's head element.

<script src="https://wjs.wurflcloud.com/wurfl.js" async></script>

In Javascript you can listen for the event:

document.addEventListener("WurflJSDetectionComplete", function(){
    console.log("WURFL.js is finished:")
    console.log(window.WURFL)
});

Please note that the event listener must be defined before the WURFL.js script tag is included to avoid a race condition.

For example, the Google Analytics code in the previous example could be fired only after WURFL.js is finished:

document.addEventListener("WurflJSDetectionComplete", function(){
    ga('send', 'pageview', {
        'dimension1': WURFL.complete_device_name,
        'dimension2': WURFL.form_factor,
        'dimension3': WURFL.is_mobile,
        'dimension4': WURFL.is_robot
    })
})

Loading WURFL.js programmatically

Some users may want to call WURFL.js programatically from within Javascript or a framework like React or Angular. In these cases, care should be taken to avoid creating a race condition between the execution of the WURFL.js script and the event handler WurflJSDetectionComplete firing, which may lead to unpredictable results. Here is an example snippet that makes use of WURFL.js' WURFLPromises feature and demonstrates loading WURFL.js via Javascript script-tag injection. This example also shows a method for WURFL.js users to receive faster and more reliable detection results for requests from browsers that participate in the User-Agent Client Hints initiative. More information regarding User-Agent Client Hints is available in the Consideration for User-Agent Client Hints for WURFL.js Business Edition section below.

const wjsPromise = new Promise((resolve, reject) => {
    const url = new URL('https://wjs.wurflcloud.com/wurfl.js')
    const runWjs = (src) => {
        const wjs = document.createElement('script')
        wjs.src = src
        wjs.async = true
        wjs.onload = () => resolve(window.WURFLPromises.complete)
        wjs.onerror = () => reject()
        document.head.appendChild(wjs)
    }

    if ('userAgentData' in navigator) {
        const hints = ['architecture', 'bitness', 'model', 'platformVersion', 'uaFullVersion', 'fullVersionList']
        navigator.userAgentData.getHighEntropyValues(hints).then((uach) => {
            url.searchParams.set('uach', JSON.stringify(uach))
            runWjs(url.toString())
        })
    } else {
        runWjs(url.toString())
    }
})

wjsPromise.then((res) => {
    // WURFL is ready to use
    console.log(res.WURFL)
}).catch(() => console.error(`Failed to load WURFL.js`))

Execution time limit

For certain devices WURFL.js will run a number of tests to identify the device. The tests are usually fast and accurate. However, if you want WURFL.js to spend more time to make the results even more reliable, you can allow more execution time. This is done by appending "?time_limit=" to the script reference. The below example will allow WURFL.js to execute for up to one second:

<script src="https://wjs.wurflcloud.com/wurfl.js?time_limit=1000"></script>

Content Security Policy

If your website uses a Content-Security-Policy (CSP), you will need to add exemptions for WURFL.js for the script-src and the connect-src directives like so:

Content-Security-Policy: script-src https://wjs.wurflcloud.com; connect-src https://wjs.wurflcloud.com

If you use a WURFL.js custom domain/CNAME, you should use that domain as the source in the CSP instead. For example if your WURFL.js custom domain is wurfljs.foo.com, then your CSP should look like this:

Content-Security-Policy: script-src https://wurfljs.foo.com; connect-src https://wurfljs.foo.com

Consideration for User-Agent Client Hints for WURFL.js Business Edition

As part of the User-Agent reduction/freeze, User-Agents from Chrome on desktop and Android platforms no longer contain information accurate enough to be solely used for device detection. As a result, we encourage you to implement and start requesting User-Agent Client Hints from your clients. We also recommend that you delegate these Client Hints to WURFLjs for the best detection experience.

Please note that User-Agent Client Hints are only available in a secure context (https).

In order to opt in to receive User-Agent Client Hints, you will need to set your server's response headers to advertise support for them using the Accept-CH header. Here's an example:

Accept-CH: sec-ch-ua-platform-version,sec-ch-ua-full-version,sec-ch-ua-full-version-list,sec-ch-ua-model,sec-ch-ua-arch,sec-ch-ua-bitness,sec-ch-ua-wow64

Next, you will want to delegate these Client Hints to WURFLjs so that they can be used as a part of the detection process. This can be achieved by setting a permissions-policy header:

permissions-policy: ch-ua-platform-version=(self "https://wjs.wurflcloud.com"),ch-ua-full-version=(self "https://wjs.wurflcloud.com"),ch-ua-full-version-list=(self "https://wjs.wurflcloud.com"),ch-ua-model=(self "https://wjs.wurflcloud.com"),ch-ua-arch=(self "https://wjs.wurflcloud.com"),ch-ua-bitness=(self "https://wjs.wurflcloud.com"),ch-ua-wow64=(self "https://wjs.wurflcloud.com")

If you are using a platform/CMS that restricts your ability to set server response headers, it may be easier to use the delegate-ch meta tag instead. Using this meta tag, you can request User-Agent Client Hints on WURFL.js's behalf and delegate them in one go:

<meta http-equiv="delegate-ch" content="sec-ch-ua https://wjs.wurflcloud.com; sec-ch-ua-bitness https://wjs.wurflcloud.com; sec-ch-ua-arch https://wjs.wurflcloud.com; sec-ch-ua-model https://wjs.wurflcloud.com; sec-ch-ua-platform https://wjs.wurflcloud.com; sec-ch-ua-platform-version https://wjs.wurflcloud.com; sec-ch-ua-full-version https://wjs.wurflcloud.com; sec-ch-ua-full-version-list https://wjs.wurflcloud.com; sec-ch-ua-mobile https://wjs.wurflcloud.com">

Additional information on adding support for User-Agent Client Hints are available in our guide here.

Accessing a User-Agent Client Hints enriched result

As mentioned in the Quick Start section above, we recommend loading WURFL.js asynchronously and listening to the WurflJSDetectionComplete event, which is generated once the device detection process is complete. Depending on the complexity of the environment and the method in which WURFL.js receives the User-Agent Client Hint data, this process can take some time to complete. As a result, if you desire intermediate device detection information while you wait for the full device detection process to complete, you can listen to the WurflJSInitComplete event.

The WurflJSInitComplete event is generated with the information that is readily available and provides reasonable defaults until WURFL.js is able to consolidate device information from various sources and generate the WurflJSDetectionComplete event.

document.addEventListener("WurflJSInitComplete", function(){
    console.log("WURFL.js is initialized and can provide intermediate device information:")
    console.log(window.WURFL)
});

Just as with the WurflJSDetectionComplete event, the event listener for the WurflJSInitComplete event must be defined before the WURFL.js script tag is included.

Capabilities

A full list of available capabilities for WURFL.js Basic/Standard/Pro can be found here.

Caching

WURFL.js Basic, Standard, and Pro allows clients to cache the WURFL response on the end-user's browser in order to increase overall performance.

When testing, it is possible to disable caching by adding debug=true to the query string.

<script src="https://wjs.wurflcloud.com/wurfl.js?debug=true" crossorigin></script>

Hostnames

Hostnames are required to associate traffic with your account. Under the Associated Hostnames section of your account, you must enter the domains and sub-domains from which you will be accessing WURFL.js. By default, WURFL.js Basic, Standard, and Pro plan 3 hostnames.

DNS CNAME Support

You can name the WURFL.js Basic, Standard, or Pro service as your own by configuring your Domain Name Server (DNS) using CNAME records. Once these CNAME records are entered in the "Associated CNAME Records" section of your account. WURFL.js will honor them.

To set up an associated CNAME record, you must configure a CNAME record that points to wjs.wurflcloud.com with your DNS provider, which may or may not be the same as your web hosting provider.

You can then enter them in the CNAME section from the left navigation menu of your account.

Customer Vault WURFL.js

Note: Your DNS changes may take up to a full day to propagate.

You will be able to refer to the service in the HTML page as (assuming your CNAME entry is wjs.your-domain.com):

<script src="https://wjs.your-domain.com/wurfl.js" crossorigin></script>

HTTPS and SSL Support

HTTPS provides a level of security and trust for users of many commercial services. WURFL.js Basic, Standard, or Pro enables customers to upload their SSL certificates through their customer vault.

Using these certificates, WURFL.js Basic/Standard/Pro can serve multiple hostnames via the CNAME records using HTTPS.

Customer Vault WURFL.js

Enrich Google Analytics 4 (GA4) with WURFL.js capabilities

A popular use case for WURFL.js is to enrich the reporting provided by Google Analytics. This allows you to add capability values returned by WURFL.js (like marketing_name or release_msrp) to your Google Analytics reports. Please note that the WURFL capabilities or device attributes that are available be used are dependent on your WURFLjs plan. If you require the use of capabilities that are not part of your plan, please contact our sales team to create a custom plan to fit your needs.

This section will outline two easy methods to integrate WURFL.js with Google Analytics 4 (GA4). One way is to use the Google Tag Manager (GTM) and the alternative is via the Google Tag (aka gtag.js or simply gtag).

Regardless of the method in which you choose to feed WURFL.js capability data into Google Analytics, you will first need to define the set of custom dimensions that GA4 should make available in your reports.

Defining Custom Dimensions in Google Analytics 4 (GA4)

GA4 offers the option to create custom dimensions. These dimensions have a small set of characteristics that need to be populated initially. The most importantant of these fields is the scope. Since the device data returned from WURFL.js is mostly tied to the user, the User scope is recommended to be used. However, the Event scope can also be used if appropriate.

Custom dimensions, for all WURFL.js capabilities that you would like to track, must be individually created in GA4 like so:

  1. In GA4 go to Administration -> Custom Definitions and add a custom dimension. A suggested naming convention for the dimension name is wurfl_<capability_name>. Define custom dimensions in Google Analytics 4

  2. Save and repeat this process to add a custom dimension for every WURFL.js capability that you wish to track in your Google Analytics reports.

Using Google Tag (gtag)

When you're using gtag directly on your website (i.e. not via GTM), a function called gtag() is exposed. This gtag() function can be used to populate the newly created custom dimentions in GA4 with the capability values from WURFL.js.

Hint: If your websites includes a script with this source https://www.googletagmanager.com/gtag/js?id=G-XXXXXX, you’re using the gtag directly on your website.

  1. Insert this code into your page's body element:
<script>
document.addEventListener("WurflJSDetectionComplete", function () {
    gtag('set', 'user_properties', {
        'wurfl_form_factor': WURFL.form_factor,
        'wurfl_pointing_method': WURFL.pointing_method,
        'wurfl_marketing_name': WURFL.marketing_name,
        'wurfl_model_name': WURFL.model_name
    });

});
</script>

Customize the user_properties object in the snippet above with the WURFL.js capabilities you need. Note that the key name must match the custom dimension names created in GA4 in the previous steps.

  1. Include the WURFL.js script tag:
<script src="https://wjs.wurflcloud.com/wurfl.js" async></script>

Note: If you are using WURFL.js Lite, use this script tag instead:

<script src="https://wurfl.io/wurfl.js" async></script>

Please ensure that the script tag to include WURFL.js is placed after the event listener code from Step 1.

  1. Once WURFL.js has completed loading, the WurflJSDetectionComplete event will fire and desired capabilities from the WURFL object can be pushed to Google Analytics. The integration is now functional.

Using Google Tag Manager (GTM)

If you’re using Google Tag Manager (GTM) to include scripts, including the GA4 tag, you can also use GTM to manage WURFL.js' integration with GA4.

  1. Assuming that you’ve added GA4 through GTM, the first step is to add a tag for WURFL.js:

a. Click Tags -> new and choose Custom HTML. Insert the following script tag:

<script src="https://wjs.wurflcloud.com/wurfl.js" async></script>

Note: If you are using WURFL.js Lite, use this script tag instead:

<script src="https://wurfl.io/wurfl.js" async></script>

Tag configuration for GTM

b. Under Triggering, choose, Initialization - All Pages

c. Give the tag a descriptive name like “insert wurfl.js” and save

  1. The next step is to create variables for each of the WURFL.js capabilities, whose values need to be sent to GA4. Note that the number and name of the variables created must match those defined in GA4 custom dimensions:

a. Go to Variables, in the User-Defined Variables section and click on New.

b. Choose Custom Javascript as the type.

c. In the text field some code is expected. Here is an example for the pointing_method capability:

function(){
  return WURFL.pointing_method;
}

Hint: Give the variable a name that is easily recognizable. For example, use the name of the WURFL.js capability. Here's a sample naming template: WURFL.<capability_name>

Variable configuration for GTM

d. Save and repeat this process until you've defined all variables to match the custom dimensions from the Defining Custom Dimensions in Google Analytics 4 (GA4) section.

  1. Now, we need to create an event in GTM to send the WURFL.js data to GA4:

a. Click on Tags -> new and choose Google Analytics: GA4 Event

b. Next, expand the User Properties section and add rows for each WURFL.js capability to track. Note that the Property Name must match the names as defined in the custom dimensions, as done in the Defining Custom Dimensions in Google Analytics 4 (GA4) section.

GA4 event configuration for GTM

Each property is assigned its value from the variables created in the previously.

c. Click the icon and select the variable that the property is for GA4 variable assignment for GTM

d. Repeat and add rows to the event until you have all the desired WURFL.js capabilities covered

e. Finally, make sure to sequence this event after the insertion of WURFL.js. Expand the Tag Sequencing section and select the WURFL.js insertion event to fire before this GA4 Event. GA4 tag sequencing for GTM

f. Save and then publish the configuration

The data is now flowing from WURFL.js via GTM to GA4. Please note that the GA4 custom dimensions will not have data usable for reporting in GA4 due to a 24 hour delay on the GA4 side. However, you can see the data flowing on the real time reports and even in the debug view, if you have that enabled. GA4 user property view

After 24 hours the data will be available in the reports as user properties, for inclusion in any reports. GA4 custom report view

Service Level Agreement (SLA)

WURFL.js Basic/Standard/Pro provides fully dedicated infrastructure for its customers and a Service Level Agreement with a 99.99% uptime target. The definition of the SLA can be found in the license agreement here.

License

2024 ScientiaMobile Incorporated.

The complete WURFL.js Basic/Standard/Pro License can be found here.