SPA: Target and Launch(Custom Events) - adobe-target/clientside GitHub Wiki

SPA: Target and Launch

Understand SPA specifics

A Single Page Application concept is to load once all the files and then render views from those files. Usually, it is an Html file with JavaScript. JavaScript is executed to add functionality to the page. In an SPA, the HTML file is sometimes barely a stub and may only exist to launch the code in the JavaScript files. The default architecture for websites is to serve up a bunch of different pages and link them together with some sort of navigation structure.

That is why every time you'll navigate thru a single page app with ordinary Target Implementation, you'll not see any other requests outside because Adobe Target is loaded then getOffers and applyOffers are executed at Page Load. When you navigate thru pages JS is executed and the browser just renders another view content, which doesn't contain Target offers, and we need to re-apply them.

Problem

When you load at.js at Page Load Event(or in html head section), at.js will get Offers from Target and apply then over your page. But if you navigate, you'll lose experiences because view was re-rendered and Target experiences were overridden with your website content.

Solution

To solve that, a solution would be, to send Custom Events from your application when user navigates with viewName in event detail. From Launch subscribe to that event, use build-in Data Element to get the eventDetail(with viewName) and pass it to Target via mbox parameters.

We'll keep Loading Target when application loads, but we'll retrieve and apply offers every time a view is rendered.

  1. Add a Custom Event to your application that will trigger a Custom Event

history.listen(location => {
   var event = new CustomEvent('at-view-start', { viewName: location.pathname });
   document.dispatchEvent(event);
});

In event detail we'll send the viewName. Now every time you'll navigate from a page to another a custom event will be triggered. In this specific case I'm using react-router-redux and I'm going to subscribe to the router history changes. For more implementation details check the application sources in index.js file.

Launch Integration

We'll have 2 rules:

  • First Rule that will be triggered at Page Top Event: Load Target + Add Global Mbox Param + Fire Global Mbox
  • Second Rule that will be triggered at Custom Event(at-view-start): Add Global Mbox Param + Fire Global Mbox

First Rule configuration

First rule will actually be triggered when Page Loads, it may be when user enters to home page or he refreshes a products page for example.

  1. Create a Custom Code Data Element(viewName) in Launch that will get the view from hash return location.hash.substr(1);

  2. Create a rule with name, like: loadPageRule

  3. Add Library Top event for loadPageRule

  4. Add a sequence of actions

  • Load Target
  • Add Params to All Mboxes -> with param viewName == %viewName%

  • Fire Global Mbox (I would prefer to hide only the main container .container selector)

First Rule should look like this:

Second Rule Configuration

Second Rule will be triggered when the custom event from react application will be fired. Every time a new view is gonna be rendered we'll retrieve Offers from Target, hide body and ApplyOffers.

  1. Create a new rule with name: fireGlobalMboxRule
  2. Add a custom event with eventType that we're dispatching, make sure you make it globally by checking any element option

  1. Add Add Params to All Mboxes action -> with param viewName == %event.detail%

%event.detail% - this is a built in Data Element, that resolves into details from the rule event, in this case is the detail that we're sending from react application, the view name - the hash from url

var event = new CustomEvent('at-view-start', { viewName: location.pathname });

  1. Add Fire Global Mbox action with body hiding enabled, with specific css hiding styles.

Create Activities in VEC

Now create an activity with few experiences one experience per view, with audience rule for custom mbox param viewName.

I have created 3 different experiences for each view:

  • Home
  • Products
  • Cart