New Marketing and Search setups
This guide walks you through a new Bloomreach Web SDK implementation for both Marketing and Search. 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 Marketing project
- A Search 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.
ImportantDon't 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.
You can also add it via Google Tag Manager if you manage scripts through a tag management system.
NoteGoogle Tag Manager only supports ES5 and throws a compilation error with the ES6-based JavaScript snippet. To avoid this:
- Add the snippet using a
<script type="text/gtmscript">tag instead of a standard<script>tag. This bypasses GTM's compilation step and allows the SDK to load correctly.- Remove the
new_experimentsconfiguration or explicitly setnew_experiments: false. GTM doesn't supportnew_experiments.
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 Search consultant
view_id: "en_US",
// Provided by your Search consultant
test_data: true,
// Ignores events in Search on production
debug: true
// Enables real-time integration mode in Search
}
},
});
brweb.start();
</script>
NoteSome 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 Marketing and Search 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 Search relevance-by-segment personalization. |
track.metadata.domain_key | String | Your Search domain key. |
track.metadata.view_id | String | Your Search catalog's view_id. For example, a locale or region. Provided by your Search consultant. |
track.metadata.test_data | Boolean | When true, Search ignores events sent from production. Use during testing and QA. |
track.metadata.debug | Boolean | When true, enables real-time integration mode in Search 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 Marketing 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 Search personalization
Search supports an optional user_id property for personalization use cases such as B2C customer targeting or B2B account-level personalization. Consult your Search implementation partner before adding this to confirm it's relevant to your setup.
NoteDon't 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 3 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 Marketing real-time segments, the Web SDK simplifies your Search integration. Instead of running 2 separate trackers, the SDK passes live segment data from Marketing to Search automatically via a single integrated tracking call.
To complete the setup, you still need to:
- Connect your Marketing project to your Search account with your Bloomreach consultant's help.
- Expose the Marketing segments you want Search to use.
- Allow time for the Search learning period to complete (typically 30 days).
For setup instructions and the full technical reference, see:
- Real-time customer segments for Search: Search setup guide
- Real-time customer segments for Search: Marketing 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 Search is receiving the expected data.
NoteThe Tracking Console extension doesn't include the pixel validation capabilities available in the Bloomreach 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 2 days ago

