New Engagement and Discovery setup
This guide walks you through a new Bloomreach Web SDK implementation for both Engagement and Discovery. Follow these steps if you're starting from scratch with no existing Bloomreach tracking on your website.
If you're adding one product to an existing setup, see:
Prerequisites
Before you start, make sure the following have been provisioned, and you have access to:
- A Data hub workspace
- A Bloomreach Engagement project
- A Bloomreach Discovery account and organization
- DNS records configured for your custom tracking domain (CTD)
Add the tracking snippet
Add the snippet below to every page on your website. Place it in the <head> before the closing </head> tag. This placement is required for non-flickering experiments to work correctly.
You can also add it via Google Tag Manager if you manage scripts through a tag management system.
Important
Do not add the tracking snippet to payment gateways or pages that handle credit card data. Tracking scripts on payment pages can be exploited to intercept sensitive financial information.
Replace the placeholder values with your actual credentials. See Find your credentials for instructions.
<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 URL
stream_id: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
// Your event stream ID
experimental: {
non_personalized_weblayers: true
},
new_experiments: {
mode: "sync"
},
customer: {
email_id: "[email protected]"
// Identified visitor's email address
},
track: {
default_properties: {
customer_tier: "gold-member"
// Custom properties added to all events
},
metadata: {
domain_key: "Pacific",
// Provided by your Discovery consultant
view_id: "en_US",
// Provided by your Discovery consultant
test_data: true,
// Ignores events in Discovery on production
debug: true
// Enables real-time integration mode in Discovery
}
},
});
brweb.start();
</script>
Note
Some privacy regulations require you to call
brweb.start()only after the visitor has granted cookie consent.
Snippet configuration reference
The table below covers the configuration parameters most relevant to a combined Engagement and Discovery setup. For the full configuration reference, see JS SDK configuration.
| Parameter | Type | Description |
|---|---|---|
target | String | Your Bloomreach API base URL. Find it in Data Hub > Workspace settings > Access Management > API > API Credentials. |
stream_id | String | Your event stream ID. Find it in Data Hub > Event streams > select your stream > Access security. |
customer.email_id | String | The identified visitor's email address. Set this when the visitor is logged in. |
track.default_properties | Object | Custom properties appended to every tracked event automatically. Use this for attributes like customer_tier that power Discovery relevance-by-segment personalization. |
track.metadata.domain_key | String | Your Discovery domain key. |
track.metadata.view_id | String | Your Discovery catalog's view_id. For example, a locale or region. Provided by your Discovery consultant. |
track.metadata.test_data | Boolean | When true, Discovery ignores events sent from production. Use during testing and QA. |
track.metadata.debug | Boolean | When true, enables real-time integration mode in Discovery and ignores events on production. Use during development. |
Update metadata after initialization
In most implementations, metadata is set once in the snippet and doesn't need to change. In some cases, for example, when a visitor switches language or region on a multi-locale site, you may need to update metadata values after brweb.start() has been called. Use the brweb.metadata() method to do this.
To update all metadata properties at once:
brweb.metadata({
domain_key: "Pacific",
view_id: "es_MX",
test_data: true,
debug: true
});
To update a single property, for example, when only the locale changes:
brweb.metadata({
view_id: "es_MX"
});
Identify visitors
Identify visitors as soon as they log in, using the hard ID configured in your Engagement project. This links their anonymous tracking history to their customer profile.
For the full identify() reference including parameters and best practices, see Customer identification in web tracking.
brweb.identify({ email_id: "[email protected]" });
When a visitor logs out, call anonymize() to clear their identifying cookies and begin tracking subsequent events under a new anonymous profile:
brweb.anonymize();
Set a user ID for Discovery personalization
Discovery supports an optional user_id property for personalization use cases such as B2C customer targeting or B2B account-level personalization. Consult your Discovery implementation partner before adding this to confirm it's relevant to your setup.
Note
Do not use personally identifiable information as the
user_idvalue. Always use an obfuscated identifier. For example, a hashed internal ID.
To include user_id in every tracked event by default, add it to the metadata object in your snippet configuration:
track: {
metadata: {
user_id: "be3e149d34ed43d4128252f2"
}
}
To update user_id at runtime (for example, after a visitor logs in), use the brweb.metadata() method:
brweb.metadata({
user_id: "be3e149d34ed43d4128252f2"
});
Configure cookie expiration
By default, tracking cookies expire after three years and are reset on every page load. You can shorten this expiration to meet your privacy policy or regional compliance requirements.
The following example sets cookie expiration to 182 days:
brweb.start({
cookies: {
expires: 182 * 24 * 3600 // 182 days, in seconds
}
});
For more configuration options, including per-category expiration and date-based expiration, see Cookie expiration in web tracking.
Set up real-time segments
If you use Engagement real-time segments, the Web SDK simplifies your Discovery integration. Instead of running two separate trackers, the SDK passes live segment data from Engagement to Discovery automatically via a single integrated tracking call.
To complete the setup, you still need to:
- Connect your Engagement project to your Discovery account with your Bloomreach consultant's help.
- Expose the Engagement segments you want Discovery to use.
- Allow time for the Discovery learning period to complete (typically 30 days).
For setup instructions and the full technical reference, see:
- Real-time customer segments for Discovery: Discovery setup guide
- Real-time customer segments for Discovery: Engagement setup guide
Verify your implementation
Use the Bloomreach Tracking Console extension to validate your tracking setup in the browser. It lets you inspect events as they fire, verify that metadata properties are passing correctly, and confirm that Discovery is receiving the expected data.
Note
The Tracking Console extension does not include the pixel validation capabilities available in the Discovery Pixel Validator Chrome extension.
What's next?
With the snippet in place, add the required tracking events to your website:
- Required events: Full reference for all page view and interaction events
- Web tracking: Customer identification, event tracking methods, and cookies
- Integrate on single-page applications: SPA-specific tracking considerations
Updated 11 days ago
