Event streams SDK

👍

Welcome note

Data hub is our new upgraded platform, which we rolled out in August 2025. It offers a single unified integration for passing your data through to your Bloomreach products.

You have access to Data hub if you've implemented with Bloomreach after August 2025.

Customers who have implemented before August 2025 should follow the existing documentation for Engagement, Discovery, and Clarity.

Setup

Bloomreach Web SDK is built on top of the Engagement JavaScript SDK and inherits the same functionality. That means those two SDKs can't run on one website at the same time due to conflicts with namespace and cookies.

The setup is similar to Engagement. Read more here: Integration

The main differences are:

  • You can get the snippet from the documentation below
  • If you are familiar with the Engagement snippet, be aware that the Unified tracking SDK is using streamID instead of a project token. You must replace the streamID with your credentials from Event streams.

Snippet

<style>.xnpe_async_hide{opacity:0 !important}</style>
<script>
  !function(e,t,n,i,o,r){const s=4e3,c="xnpe_async_hide";function a(e){if("number"!=typeof e)return e;const t=new Date;return new Date(t.getTime()+1e3*e)}function p(e){return e.reduce((function(e,t){return e[t]=function(){e._.push([t.toString(),arguments])},e}),{_:[]})}function m(e,t,n){const i=n.createElement(t);i.src=e;const o=n.getElementsByTagName(t)[0];return o.parentNode.insertBefore(i,o),i}function l(e){return"[object Date]"===Object.prototype.toString.call(e)}r.target=r.target||"//api.exponea.com",r.file_path=r.file_path||r.target+"/js/brweb.min.js",o[t]=p(["anonymize","initialize","identify","getSegments","update","track","trackLink","trackEnhancedEcommerce","getHtml","showHtml","showBanner","showWebLayer","ping","getAbTest","loadDependency","getRecommendation","reloadWebLayers","_preInitialize","_initializeConfig","metadata"]),o[t].notifications=p(["isAvailable","isSubscribed","subscribe","unsubscribe"]),o[t].segments=p(["subscribe"]),o[t]["snippetVersion"]="v3.1.1",function(e,t,n,i){e[i]={sdk:e[n],sdkObjectName:n,skipExperiments:!!t.new_experiments,path:t.target,streamId:t.stream_id}}(o,r,t,i),function(e,t,n){m(e.file_path,t,n)}(r,n,e),function(e,t,n,i,o,r,p,u){if(!e.new_experiments)return;!0===e.new_experiments&&(e.new_experiments={});const _=e.new_experiments.hide_class||c,f=e.new_experiments.timeout||s,d=encodeURIComponent(r.location.href);let g;e.cookies&&e.cookies.expires&&("number"==typeof e.cookies.expires||l(e.cookies.expires)?g=a(e.cookies.expires):e.cookies.expires.tracking&&("number"==typeof e.cookies.expires.tracking||l(e.cookies.expires.tracking))&&(g=a(e.cookies.expires.tracking))),g&&g<new Date&&(g=void 0);const b=e.target+"/webxp/streams/"+e.stream_id+"/"+t+"/"+(u.exec(p.cookie)||[0,"new"])[1]+"/modifications.min.js?http-referer="+d+"&timeout="+f+"ms"+(g?"&cookie-expires="+Math.floor(g.getTime()/1e3):"");"sync"===e.new_experiments.mode&&r.localStorage.getItem("__exponea__sync_modifications__")?function(e,t,n,i,o){n[o][t]="<"+t+' src="'+e+'"></'+t+">",i.writeln(n[o][t]),i.writeln("<"+t+">!"+o+".init && document.writeln("+o+"."+t+'.replace("/'+t+'/", "/'+t+'-async/").replace("><", " async><"))</'+t+">")}(b,t,r,p,n):function(e,t,n,i,o,r,s,c){r.documentElement.classList.add(e);const a=m(n,i,r);function p(){o[c].init||m(n.replace("/"+i+"/","/"+i+"-async/"),i,r)}function l(){r.documentElement.classList.remove(e)}a.onload=p,a.onerror=p,o.setTimeout(l,t),o[s]._revealPage=l}(_,f,b,t,r,p,o,n)}(r,n,i,0,t,o,e,RegExp("__exponea_etc__"+"=([\\w-]+)")),function(e,t,n){var i;e[t]._initializeConfig(n),(null===(i=n.experimental)||void 0===i?void 0:i.non_personalized_weblayers)&&e[t]._preInitialize(n),e[t].start=function(i){i&&Object.keys(i).forEach((e=>n[e]=i[e])),e[t].initialize(n)}}(o,t,r)}(document,"brweb","script","webxpClient",window,{
  target: "https://api.XXXXXXX.dev", // your Bloomreach API base endpoint
    stream_id: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", // your Bloomreach Event stream ID
    experimental: {
        non_personalized_weblayers: true
    },
    new_experiments: { mode: "sync" },
    customer: {
        email_id: "[email protected]" // identified visitor identity for Engagement
    },
    track: {
        default_properties: { // custom properties to be added to all events
            customer_tier: "gold-member" // your additional custom segments (primarily for Discovery)
        },
        metadata: { // optional metadata properties which control specific functionality
            domain_key: "Pacific", // Bloomreach provided key for Discovery
            view_id: "en_US", // Bloomreach provided key for Discovery
            test_data: true, // enables Discovery ignore on production
            debug: true // enables Discovery real-time Integration mode and ignore on production
        }
    },
});
brweb.start(); // some regulations may require you to start() only after visitor has granted cookie consent
</script>

The target parameter is the endpoint which is available in the Event streams menu:

For your Bloomreach API base endpointtarget, you can also find the URL in Data Hub > Workspace settings > Access Management > API > API Base URL.

Configuration

The configuration is taken from the Engagement JavaScript SDK. Read more here: JS SDK Configuration

There are new configuration options that are unique to the Unified tracking JavaScript SDK:

  • Support for metadata
  • Support for Real-time segments (RTS)

Metadata

  • domain_key: Ask your Discovery technical consultant for instructions about what the correct value should be here
  • view_id: Ask your Discovery technical consultant for instructions about what the correct value should be here

Real-time segments (RTS)

To enable RTS, add this code to your configuration object:

  cdp_segments: {
    rts: true
  }

Custom tracking domain (CTD)

For more information on setting up a Custom tracking domain, read here: Custom Tracking Domain (CTD).