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.

ParameterTypeDescription
targetStringYour Bloomreach API base URL. Find it in Data Hub > Workspace settings > Access Management > API > API Credentials.
stream_idStringYour event stream ID. Find it in Data Hub > Event streams > select your stream > Access security.
customer.email_idStringThe identified visitor's email address. Set this when the visitor is logged in.
track.default_propertiesObjectCustom properties appended to every tracked event automatically. Use this for attributes like customer_tier that power Discovery relevance-by-segment personalization.
track.metadata.domain_keyStringYour Discovery domain key.
track.metadata.view_idStringYour Discovery catalog's view_id. For example, a locale or region. Provided by your Discovery consultant.
track.metadata.test_dataBooleanWhen true, Discovery ignores events sent from production. Use during testing and QA.
track.metadata.debugBooleanWhen 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_id value. 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:

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: