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 
Overviewsection offers a global view of available options - The 
Detailssection 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.ddoptionsYou must configure the JS Tag by adding properties to the
window.ddoptionsobject as seen on the code snippet displayed here.
Overview
| Name | Description | Type | Default value | 
|---|---|---|---|
abortAsyncOnChallengeDisplay | Aborts requests blocked by DataDome | Boolean | true | 
ajaxListenerPath | URL patterns to intercept protected requests and display challenges for blocked traffic | Boolean | Array<String> | Array<URLParts> | true | 
ajaxListenerPathExclusion | URL patterns to exclude from intercepting protected requests | Array<String> | Array<URLParts> | ['https://www.google-analytics.com'] | 
challengeLanguage | Forces a specific language to display challenges on requests sent with XMLHttpRequest or fetch | String | Empty | 
disableAutoRefreshOnCaptchaPassed | Disables the automatic page refresh that occurs after a challenge is passed | Boolean | false | 
enableServiceWorkerPlugin | Listens to events from the @datadome/service-worker-plugin package to display challenges for requests blocked in a service worker context | Boolean | false | 
enableTagEvents | Enables the dispatch of events from the JS Tag | Boolean | false | 
endpoint | URL to use for collecting signals | String | 'https://api-js.datadome.co/js/' or the /js/ route on the JS Tag's origin, e.g. https://dd.example.com/js/ if the JS Tag is served from https://dd.example.com/tags.js | 
exposeCaptchaFunction | Exposes a global function to display challenges for blocked traffic, named displayDataDomeCaptchaPage | Boolean | false | 
overrideAbortFetch | Ensures the interception of error responses to display challenges for blocked traffic | Boolean | true | 
replayAfterChallenge | Enables automatic replay of a request sent with XMLHttpRequest or fetch after passing a challenge | Boolean | false | 
sessionByHeader | Attaches the datadome cookie to XHR and Fetch requests on a custom header | Boolean | false | 
withCredentials | Enables credentials on XHR and Fetch requests | Boolean | false | 
Details
abortAsyncOnChallengeDisplay
abortAsyncOnChallengeDisplayWhy 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
403response (e.g. to run an error handler), you might need to disable this behavior.
How to use abortAsyncOnChallengeDisplay to stop aborting blocked requests
abortAsyncOnChallengeDisplay to stop aborting blocked requests- Add 
abortAsyncOnChallengeDisplay: falseto thewindow.ddoptionsconfiguration object to disable it. 
ajaxListenerPath
ajaxListenerPathWhy should I use
ajaxListenerPath?The
ajaxListenerPathoption 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,sessionByHeaderandoverrideAbortFetchon matching requests.
How to use ajaxListenerPath to enforce challenge display
ajaxListenerPath to enforce challenge displayIt 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
String parametersEach 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'
  ]
};
URLs that will match with the example configuration
https://domain.com/apihttps://staging.domain.com/carthttps://partner.example.com/apihttps://partner.example.com/info?referrer=domain.com
Advanced: matching URLs with URLParts parameters
URLParts parametersURLParts 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:
| Name | Description | Type | Default value | 
|---|---|---|---|
host | Matches the host of a URL as defined here | String | N/A | 
path | Matches the path of a URL as defined here, including the leading / character | String | N/A | 
query | Matches the query string of a URL as defined here, including the leading ? character | String | N/A | 
fragment | Matches the fragment identifier of a URL as defined here, including the leading # character | String | N/A | 
strict | If set to true, the parameter will match strictly with the combination of all its properties | Boolean | false | 
About the
strictmodeBy default, a
URLPartsparameter will match a URL if at least one of its properties matched.If all the properties of a
URLPartsparameter must match, you must addstrict: trueto 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' }
  ]
};
URLs that will match with the example configuration
https://domain.com/apihttps://staging.domain.com/carthttps://partner.example.com/api
URLs that will not match with the example configuration
https://partner.example.com/info?referrer=domain.com
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' }
  ]
};
URLs that will match with the example configuration
https://domain.com/api/78a93c7/loginhttps://staging.domain.com/api/test/login
Other possible configurations
- Using 
ajaxListenerPath: true(the default value) will match request URLs with the host of the current document. - Passing a single 
Stringvalue toajaxListenerPathis equivalent to having an array with a single value. 
ajaxListenerPathExclusion
ajaxListenerPathExclusionWhy should I use
ajaxListenerPathExclusion?The
ajaxListenerPathExclusionoption can be used to filter out request URLs that could match with theajaxListenerPathoption.Matching requests will also be excluded from applying options such as
withCredentials,sessionByHeaderandoverrideAbortFetch.
How to use ajaxListenerPathExclusion to exclude URL patterns from matching with ajaxListenerPath
ajaxListenerPathExclusion to exclude URL patterns from matching with ajaxListenerPath- Follow the same instructions as for the 
ajaxListenerPathoption. 
challengeLanguage
challengeLanguageWhy should I use
challengeLanguage?By default, challenges will be displayed with the main language seen on the Accept-Language request header, which reflects the user preferences from the browser.
If you prefer to use languages that are defined as user preferences on your application, you can rely on this option to enforce them.
How to use challengeLanguage to force a language when displaying a challenge
challengeLanguage to force a language when displaying a challenge- Add 
challengeLanguage: 'xx'to thewindow.ddoptionsconfiguration object and replacexxwith the identifier of the language to use- Refer to the documentation for DataDome CAPTCHA to get a list of supported language identifiers
 
 
disableAutoRefreshOnCaptchaPassed
disableAutoRefreshOnCaptchaPassedWhy 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
XMLHttpRequestorFetch.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
disableAutoRefreshOnCaptchaPassed to disable the automatic page reload after passing a challenge- Add 
disableAutoRefreshOnCaptchaPassed: trueto thewindow.ddoptionsconfiguration object to disable it. 
enableServiceWorkerPlugin
enableServiceWorkerPluginWhy should I use
enableServiceWorkerPlugin?If your application uses a service worker to proxy some of its requests, the JS Tag will not be able to intercept this traffic in order to display challenges when it is blocked.
This option is required to receive events from the @datadome/service-worker-plugin package in order to display challenges as expected.
The @datadome/service-worker-plugin is a dependency that has to be imported in your service worker.
How to use enableServiceWorkerPlugin to display challenges for requests blocked in service workers
enableServiceWorkerPlugin to display challenges for requests blocked in service workers- Add 
enableServiceWorkerPlugin: trueto thewindow.ddoptionsconfiguration object to enable it. - Add the @datadome/service-worker-plugin to your service worker following the instructions from its description.
 
enableTagEvents
enableTagEventsWhy 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
enableTagEvents to dispatch events for specific actions- Add 
enableTagEvents: trueto thewindow.ddoptionsconfiguration object to enable it. - Add event listeners on the global 
windowobject 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)
});
Use the
detailpropertyAll events dispatched by this option will be instances of
CustomEvent, so all properties documented below will be accessible on the detail property of the event.
Event details
| Name | Description | Event properties (on .detail) | 
|---|---|---|
dd_ready | Dispatched after the JS Tag has been loaded and executed | context | 
dd_post | Dispatched after the JS Tag has just sent a payload | context, endpointUrl | 
dd_post_done | Dispatched 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 request | context, url, responseUrl | 
dd_response_displayed ⚠️ | Dispatched after the JS Tag has displayed a challenge for a blocked request | context, responseType, responseUrl, rootElement | 
dd_response_error ⚠️ | Dispatched after the JS Tag has failed to display a challenge for a blocked request | context, responseUrl, rootElement, reason | 
dd_response_passed ⚠️ | Dispatched after the user has passed a challenge | context, responseType | 
dd_response_unload⚠️ | Dispatched when the challenge is being unloaded | context, responseType | 
About events marked with a ⚠️ sign
These events can only be dispatched for requests that were sent using
XMLHttpRequestorFetch.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
| Name | Description | Type | 
|---|---|---|
context | Name of the script that generated the event; should always be 'tags' | String | 
endpointUrl | URL of the endpoint where the payload was sent | String | 
reason | Human-readable message about a potential root cause for the error | String | 
responseUrl | URL of the challenge to display; can be required if the exposeCaptchaFunction is enabled | String | 
responseType | Type of the challenge to display; can be 'captcha', 'devicecheck' or 'hardblock' | String | 
rootElement | Reference to the parent DOM element that holds the div element containing the challenge | Element | 
url | URL of the request that was blocked | String | 
endpoint
endpointWhy 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
endpointvalue is automatically inferred by the JS Tag by using the/js/route from the same origin.
- If the script loading source is: https://my.customdomain.com/tags.js
 - The inferred endpoint will be: https://my.customdomain.com/js/
 You should configure the
endpointoption 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
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
endpoint  to send signals to a custom domain- Add the 
endpointoption to thewindow.ddoptionswith 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
exposeCaptchaFunctionWhy 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
enableTagEventsoption, you might need this option to allow your application to trigger the display itself.
How to use exposeCaptchaFunction to handle challenge display
exposeCaptchaFunction to handle challenge display- Add 
exposeCaptchaFunction: trueto thewindow.ddoptionsconfiguration 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 areurl: The URL of the challenge to display. This URL can be retrieved by subscribing to thedd_blockedevent and reading theevent.detail.responseUrlproperty.
Note that this event is only dispatched if theenableTagEventsoption is set totrue.
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 thedocument.bodyelement.
 - The automatic display performed by the JS Tag will be disabled.
 
overrideAbortFetch
overrideAbortFetchWhy should I use
overrideAbortFetch?By default, the JS Tag prevents
AbortSignaltokens 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
AbortSignaltokens is essential for your application.
How to use overrideAbortFetch to disable overrides of Request instances using AbortSignal tokens
overrideAbortFetch to disable overrides of Request instances using AbortSignal tokens- Add 
overrideAbortFetch: falseto thewindow.ddoptionsconfiguration object to disable it. 
Matching with
ajaxListenerPathandajaxListenerPathExclusionThis option is only applied on requests with a URL that matches with the configuration defined on the
ajaxListenerPathandajaxListenerPathExclusionoptions.
replayAfterChallenge
replayAfterChallengeWhy should I use
replayAfterChallenge?Enable this option if you need requests sent with
XMLHttpRequestorfetchto be replayed by the JS Tag after being challenged with a CAPTCHA or a Device Check response.The replay will run after the end user successfully passed it — for example, to re-submit a login form or a search query.
How to use replayAfterChallenge to enable request replay
replayAfterChallenge to enable request replay- Add 
replayAfterChallenge: trueto thewindow.ddoptionsconfiguration object to enable it. - Make sure that the 
ajaxListenerPathoption covers requests that must be replayed. 
Important notes
- Replaying a request sent with
 XMLHttpRequestasynchronously requires that the event listener(s) (i.e. for theloadevent) used to read the response remain attached to the request instance. If not, the replay will not yield the expected result to the application.- Enabling
 replayAfterChallengewill also activate disableAutoRefreshOnCaptchaPassed to allow replays to take place instead of reloading pages.- If multiple requests were blocked concurrently, only the first one will be replayed.
 
sessionByHeader
sessionByHeaderWhy 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 thedatadomecookie cannot be saved while theSameSite=Laxattribute is used, because it will be attached to that API's domain (e.g.Domain=.other.com).- You don't want to use the
 withCredentialsoption because it sends all cookies that match with the request's domain.
Prerequisites for sessionByHeader
sessionByHeader- You must configure your CORS headers with the following rules:
- Allow the 
x-datadome-clientidrequest header by includingAccess-Control-Allow-Headers: x-datadome-clientidon preflight responses (i.e. for requests using theOPTIONSmethod): - Allow JavaScript to access custom response headers named 
x-set-cookieandx-dd-bby includingAccess-Control-Expose-Headers: x-set-cookie, x-dd-bon non-preflight responses: 
 - Allow the 
 
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
sessionByHeader to work around domain restrictions on cookies- Add 
sessionByHeader: trueto thewindow.ddoptionsconfiguration object to enable it. 
Matching with
ajaxListenerPathandajaxListenerPathExclusionThis option is only applied on requests with a URL that matches with the configuration defined on the
ajaxListenerPathandajaxListenerPathExclusionoptions.
withCredentials
withCredentialsWhy should I use
withCredentials?By default, when an application makes cross-origin requests with
XMLHttpRequestorFetch, the request will not include credentials, i.e. cookies and authorization tokens.Since protected requests must include the
datadomecookie to ensure optimal protection, this option might be required for requests that ignore it.
Prerequisites for withCredentials
withCredentials- You must configure your preflight responses to allow credentials by including 
Access-Control-Allow-Credentials: truein their headers 
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
Avoid using wildcards on
Access-Control-Allow-OriginReturning
Access-Control-Allow-Origin: *is not allowed when usingAccess-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
withCredentials to enforce cookies on cross-origin requests- Add 
withCredentials: trueto thewindow.ddoptionsconfiguration object to enable it. 
It will be equivalent to enabling the withCredentials option on XMLHttpRequest instances, and the credentials option for Fetch calls.
Matching with
ajaxListenerPathandajaxListenerPathExclusionThis option is only applied on requests with a URL that matches with the configuration defined on the
ajaxListenerPathandajaxListenerPathExclusionoptions.
Updated 3 months ago
