Skip to content

Consent managers

Consent platforms block unrecognised third-party scripts by default, usually by rewriting the tag to type="text/plain" so the browser never executes it. That produces the single most confusing failure mode there is: an empty host element, no console error, and a widget that looks broken rather than blocked.

The statement your privacy team needs

OddsRelay widgets set no cookies and store no analytics or advertising identifiers. They do not track visitors across sites and they contain no third-party analytics SDK. The only data they place on a device is the visitor's own saved settings, itemised on the storage page.

On that basis they can be categorised as strictly necessary or functional rather than marketing.

Per-platform tags

PlatformAdd to the script tagWhy
Cookiebotdata-cookieconsent="ignore"Cookiebot blocks unrecognised third-party scripts by rewriting the tag to type="text/plain" until consent. This attribute tells it the script is exempt.
OneTrustclass="optanon-category-C0001"C0001 is OneTrust's strictly-necessary category. Without an explicit class, OneTrust auto-categorises against its own database and an unknown script on a betting-adjacent domain is a likely marketing classification.
Other / customcategorise as strictly-necessary or functionalThe widget is functionality your visitor asked for and stores nothing that identifies them across sites. If your policy is to gate everything anyway, use the consent-gated recipe below instead.
Cookiebot
<script src="https://oddsrelay.io/widgets/v1/oddsrelay-widgets.js"
        data-cookieconsent="ignore"
        crossorigin="anonymous" async></script>
OneTrust
<script src="https://oddsrelay.io/widgets/v1/oddsrelay-widgets.js"
        class="optanon-category-C0001"
        crossorigin="anonymous" async></script>

If you would rather gate it anyway

Plenty of teams gate every third-party script regardless of category, and that is a perfectly reasonable policy. Load the bundle from your consent-granted callback instead. Widgets already on the page mount as soon as the bundle arrives; if you add host elements later, call window.OddsRelay.scan().

Consent-gated load
<!-- Blocked until your consent callback runs -->
<script type="text/plain" data-src="https://oddsrelay.io/widgets/v1/oddsrelay-widgets.js"></script>

<!-- In your consent-granted callback -->
<script>
  function loadOddsRelayWidgets() {
    var s = document.createElement("script");
    s.src = "https://oddsrelay.io/widgets/v1/oddsrelay-widgets.js";
    s.crossOrigin = "anonymous";
    s.async = true;
    // The bundle scans the document when it loads, so any host elements
    // already on the page mount by themselves. Call scan() again only if
    // you add more afterwards.
    document.head.appendChild(s);
  }
</script>

The visible cost is that visitors who decline see an empty space where the widget was. If that matters on a page where the widget is the content, categorising it as functional is the better answer.

Checking whether consent is the problem

View the rendered page source and look at our script tag. If it reads type="text/plain", or the src has been moved to a data- attribute, your consent manager rewrote it and the browser never ran it. If the tag is untouched and the widget is still missing, it is a Content-Security-Policy or a mount-timing problem instead. See CSP and troubleshooting.