How to configure the JavaScript Tag

Having the right configuration for the JS Tag is essential to allow DataDome to work in optimal conditions depending on your web app.

This page will explain how to use the right options for the JS Tag, providing you with a better understanding and more control over your client-side integration with DataDome:

  • The Overview section offers a global view of available options
  • The Details section goes over the purpose of each option and instructions on how to use them

❗️

Impacts of a bad configuration

Configuration issues can lead to poor user experience for your users and/or sub-optimal detection on bot threats.

Please feel free to review your JS Tag configuration with the help of our technical support if you have any doubt.

📘

Defining your configuration on window.ddoptions

You must configure the JS Tag by adding properties to the window.ddoptions object as seen on the code snippet displayed here.

Overview

NameDescriptionTypeDefault value
abortAsyncOnChallengeDisplayAborts requests blocked by DataDomeBooleantrue
ajaxListenerPathURL patterns to intercept protected requests and display challenges for blocked trafficBoolean | Array<String> | Array<URLParts>true
ajaxListenerPathExclusionURL patterns to exclude from intercepting protected requestsArray<String> | Array<URLParts>['https://www.google-analytics.com']
disableAutoRefreshOnCaptchaPassedDisables the automatic page refresh that occurs after a challenge is passedBooleanfalse
enableTagEventsEnables the dispatch of events from the JS TagBooleanfalse
endpointURL to use for collecting signalsString'https://api-js.datadome.co/js/' or the /js/ route on the JS Tag's origin
exposeCaptchaFunctionExposes a global function to display challenges for blocked traffic, named displayDataDomeCaptchaPageBooleanfalse
overrideAbortFetchEnsures the interception of error responses to display challenges for blocked trafficBooleantrue
sessionByHeaderAttaches the datadome cookie to XHR and Fetch requests on a custom headerBooleanfalse
withCredentialsEnables credentials on XHR and Fetch requestsBooleanfalse

Details

abortAsyncOnChallengeDisplay

📘

Why should I use abortAsyncOnChallengeDisplay?

By default, the JS Tag will abort requests that got blocked.

If your application needs to know when a request was blocked and got a 403 response (e.g. to run an error handler), you might need to disable this behavior.

How to use abortAsyncOnChallengeDisplay to stop aborting blocked requests

  • Add abortAsyncOnChallengeDisplay: false to the window.ddoptions configuration object to disable it.

ajaxListenerPath

📘

Why should I use ajaxListenerPath?

The ajaxListenerPath option is the most important parameter for the JS Tag; it is required to intercept XHR and Fetch requests protected by DataDome based on matching URL patterns.

Its main purpose is to properly display challenges (e.g. CAPTCHA and Device Check) when one of these requests has been blocked, but also to apply options such as withCredentials, sessionByHeader and overrideAbortFetch on matching requests.

How to use ajaxListenerPath to enforce challenge display

It is recommended to define this option as an array to make it easier to add parameters.

ℹ️ It is possible to mix String and URLParts parameters in the same array.

window.ddoptions = {
  ajaxListenerPath: [
    // Add your parameters here
  ]
};

Most used: matching URLs with String parameters

Each parameter from the array will be used as a substring to match against the complete URL of a request.

For example, the example below will look for domain.com and /api not only on the host or the path of a URL, but also on the query string and the anchor.

window.ddoptions = {
  ajaxListenerPath: [
    'domain.com',
    '/api'
  ]
};

Advanced: matching URLs with URLParts parameters

URLParts parameters can be used to target specific parts of a URL instead of its entire value.

The structure of a URLParts parameter can include these properties, with at least one URL property:

NameDescriptionTypeDefault value
hostMatches the host of a URL as defined hereStringN/A
pathMatches the path of a URL as defined here, including the leading / characterStringN/A
queryMatches the query string of a URL as defined here, including the leading ? characterStringN/A
fragmentMatches the fragment identifier of a URL as defined here, including the leading # characterStringN/A
strictIf set to true, the parameter will match strictly with the combination of all its propertiesBooleanfalse

🚧

About the strict mode

By default, a URLParts parameter will match a URL if at least one of its properties matched.

If all the properties of a URLParts parameter must match, you must add strict: true to the parameter.

For example, we can convert the previous parameters so that domain.com can only match hosts and /api can only match paths:

window.ddoptions = {
  ajaxListenerPath: [
    { host: 'domain.com' },
    { path: '/api' }
  ]
};

Using wildcards for dynamic patterns

Wildcards (i.e. * characters) can be used to match with any string of characters in the middle of a pattern.

For example, the configuration below could match with any path that starts with /api and ends with /login:

window.ddoptions = {
  ajaxListenerPath: [
    { path: '/api/*/login' }
  ]
};

Other possible configurations

  • Using ajaxListenerPath: true (the default value) will match request URLs with the host of the current document.
  • Passing a single String value to ajaxListenerPath is equivalent to having an array with a single value.

ajaxListenerPathExclusion

📘

Why should I use ajaxListenerPathExclusion?

The ajaxListenerPathExclusion option can be used to filter out request URLs that could match with the ajaxListenerPath option.

Matching requests will also be excluded from applying options such as withCredentials, sessionByHeader and overrideAbortFetch.

How to use ajaxListenerPathExclusion to exclude URL patterns from matching with ajaxListenerPath

  • Follow the same instructions as for the ajaxListenerPath option.

disableAutoRefreshOnCaptchaPassed

📘

Why should I use disableAutoRefreshOnCaptchaPassed?

By default, the JS Tag will force a page reload after passing a challenge for a blocked request that was made with XMLHttpRequest or Fetch.

If you would rather go back to the page in its current state (e.g. to avoid losing form data after a block), you can use this option to disable that automatic reload behavior.

How to use disableAutoRefreshOnCaptchaPassed to disable the automatic page reload after passing a challenge

  • Add disableAutoRefreshOnCaptchaPassed: true to the window.ddoptions configuration object to disable it.

enableTagEvents

📘

Why should I use enableTagEvents?

If you need to execute your own logic following specific events handled by the JS Tag, you can enable this option to let it dispatch global events on which your application can subscribe.

How to use enableTagEvents to dispatch events for specific actions

  • Add enableTagEvents: true to the window.ddoptions configuration object to enable it.
  • Add event listeners on the global window object to subscribe to the events of your choice.
    • You can find more details about each event below in the next section.
window.addEventListener('dd_response_passed', (event) => {
  // Implement your own logic to be executed after a user passed a challenge
  // (e.g. CAPTCHA or Device Check)
});

Event details

NameDescriptionEvent properties
dd_readyDispatched after the JS Tag has been loaded and executedcontext
dd_postDispatched after the JS Tag has just sent a payloadcontext, endpointUrl
dd_post_doneDispatched after the JS Tag received a response to a payload (does not apply if the payload was sent using the sendBeacon function)context, endpointUrl
dd_blocked ⚠️Dispatched after the JS Tag has intercepted a response for a blocked requestcontext, url, responseUrl
dd_response_displayed ⚠️Dispatched after the JS Tag has displayed a challenge for a blocked requestcontext, responseType, responseUrl, rootElement
dd_response_error ⚠️Dispatched after the JS Tag has failed to display a challenge for a blocked requestcontext, responseUrl, rootElement, reason
dd_response_passed ⚠️Dispatched after the user has passed a challengecontext, responseType
dd_response_unload⚠️Dispatched when the challenge is being unloadedcontext, responseType

🚧

About events marked with a ⚠️ sign

These events can only be dispatched for requests that were sent using XMLHttpRequest or Fetch.

Blocked navigation requests (i.e. HTTP requests to load a document) cannot be intercepted by the JS Tag, since the document that is supposed to load it would not be rendered.

Property details

NameDescriptionType
contextName of the script that generated the event; should always be 'tags'String
endpointUrlURL of the endpoint where the payload was sentString
reasonHuman-readable message about a potential root cause for the errorString
responseUrlURL of the challenge to display; can be required if the exposeCaptchaFunction is enabledString
responseTypeType of the challenge to display; can be 'captcha', 'devicecheck' or 'hardblock'String
rootElementReference to the parent DOM element that holds the div element containing the challengeElement
urlURL of the request that was blockedString

endpoint

📘

Why should I use endpoint?

If you are hosting the JS Tag on your own infrastructure, payloads generated by the JS Tag need to be sent to a custom endpoint instead of the default one.

When not defined, the endpoint value is automatically inferred by the JS Tag by using the /js/ route from the same origin.

You should configure the endpoint option if:

  • You don't load the JS Tag from the default URL (https://js.datadome.co/tags.js) and don't use our First-Party JS Tag feature
  • You don't expose the JS Tag under its original name (tags.js)
  • The endpoint URL is different from the one inferred by the JS Tag

Prerequisites for endpoint

  • Loading the JS Tag from a custom URL (see this section for more details)

How to use endpoint to send signals to a custom domain

  • Add the endpoint option to the window.ddoptions with the URL of the API that will receive payloads from the JS Tag.

For example, let's say you set up the JS Tag to be served from https://dd.example.com/tags.js, but signals should be collected on from a different origin and/or route:

window.ddoptions = {
  endpoint: 'https://collect.example.com/js/'
}

exposeCaptchaFunction

📘

Why should I use exposeCaptchaFunction?

By default, the JS Tag handles the lifecycle of challenges on blocked requests.

If you need more control on that lifecycle, and used the enableTagEvents option, you might need this option to allow your application to trigger the display itself.

How to use exposeCaptchaFunction to handle challenge display

  • Add exposeCaptchaFunction: true to the window.ddoptions configuration object to enable it.

This will have two outcomes:

  • It will expose the display function used by the JS Tag as window.displayDataDomeResponsePage(url, root). This function takes two parameters which are
    • url: The URL of the challenge to display. This URL can be retrieved by subscribing to the dd_blocked event and reading the event.detail.responseUrl property.
      Note that this event is only dispatched if the enableTagEvents option is set to true.
      For more details, see the section about the enableTagEvents option.
    • root (optional): The DOM element that will serve as the parent for the challenge frame.
      If not provided, the challenge frame will be attached to the document.body element.
  • The automatic display performed by the JS Tag will be disabled.

overrideAbortFetch

📘

Why should I use overrideAbortFetch?

By default, the JS Tag prevents AbortSignal tokens from aborting Fetch requests to ensure that challenges are properly displayed on blocked requests.

You might need to disable this behavior if the usage of these AbortSignal tokens is essential for your application.

How to use overrideAbortFetch to disable overrides of Request instances using AbortSignal tokens

  • Add overrideAbortFetch: false to the window.ddoptions configuration object to disable it.

sessionByHeader

📘

Why should I use sessionByHeader?

You might need this option in two cases:

  • Your application is hosted on a domain (e.g. www.example.com) that cannot match with the domain of third-party APIs (e.g. api.other.com), so the datadome cookie cannot be saved while the SameSite=Lax attribute is used, because it will be attached to that API's domain (e.g. Domain=.other.com).
  • You don't want to use the withCredentials option because it sends all cookies that match with the request's domain.

Prerequisites for sessionByHeader

Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Headers: x-datadome-clientid
Access-Control-Expose-Headers: x-set-cookie, x-dd-b

How to use sessionByHeader to work around domain restrictions on cookies

  • Add sessionByHeader: true to the window.ddoptions configuration object to enable it.

withCredentials

📘

Why should I use withCredentials?

By default, when an application makes cross-origin requests with XMLHttpRequest or Fetch, the request will not include credentials, i.e. cookies and authorization tokens.

Since protected requests must include the datadome cookie to ensure optimal protection, this option might be required for requests that ignore it.

Prerequisites for withCredentials

Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true

🚧

Avoid using wildcards on Access-Control-Allow-Origin

Returning Access-Control-Allow-Origin: * is not allowed when using Access-Control-Allow-Credentials: true.

A single origin must be returned, as seen in the previous example.

How to use withCredentials to enforce cookies on cross-origin requests

  • Add withCredentials: true to the window.ddoptions configuration object to enable it.

It will be equivalent to enabling the withCredentials option on XMLHttpRequest instances, and the credentials option for Fetch calls.