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](https://my.scientiamobile.com/wurfljs/app/signup) account, you will simply need to enter the hostnames of the websites from which you intend to use WURFL.js: ![Customer Vault WURFL.js](https://docs.scientiamobile.com/img/wurfl_js_domains.jpg) 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: **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. 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: *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](https://www.chromium.org/updates/ua-reduction/), 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: Additional information on adding support for User-Agent Client Hints are available in our guide [here](https://docs.scientiamobile.com/guides/implementing-useragent-clienthints). *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](https://www.scientiamobile.com/capabilities/?products%5B%5D=wurfl-js). 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. 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](https://docs.scientiamobile.com/img/wurfl_js_cname.jpg) *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`): 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](https://docs.scientiamobile.com/img/wurfl_js_ssl_cert.jpg) 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](https://www.scientiamobile.com/general-inquiry/) 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_`. ![Define custom dimensions in Google Analytics 4](https://docs.scientiamobile.com/img/ga4_define_custom_dimensions.png) 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: ```html ``` 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. 2. Include the WURFL.js script tag: ```html ``` Note: If you are using WURFL.js Lite, use this script tag instead: ```html ``` Please ensure that the script tag to include WURFL.js is placed after the event listener code from Step 1. 3. 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: ```html ``` Note: If you are using WURFL.js Lite, use this script tag instead: ```html ``` ![Tag configuration for GTM](https://docs.scientiamobile.com/img/ga4_tag_configuration_gtm.png) b. Under `Triggering`, choose, `Initialization - All Pages` c. Give the tag a descriptive name like “insert wurfl.js” and save 2. 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.` ![Variable configuration for GTM](https://docs.scientiamobile.com/img/ga4_variable_configuration_gtm.png) 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. 3. 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](https://docs.scientiamobile.com/img/ga4_event_configuration_gtm.png) 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](https://docs.scientiamobile.com/img/ga4_variable_assignment_gtm.png) 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](https://docs.scientiamobile.com/img/ga4_tag_sequencing_gtm.png) 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](https://docs.scientiamobile.com/img/ga4_user_property_view.png) After 24 hours the data will be available in the reports as `user properties`, for inclusion in any reports. ![GA4 custom report view](https://docs.scientiamobile.com/img/ga4_custom_report_view.png) 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](https://www.scientiamobile.com/page/wurfl-js-and-wit-be-terms-of-service). License ------- 2024 ScientiaMobile Incorporated. The complete WURFL.js Basic/Standard/Pro License can be found [here](https://www.scientiamobile.com/terms-service-wurfl-js-imageengine-be).