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.
- 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.
-
Create a Custom Code Data Element(viewName) in Launch that will get the view from hash
return location.hash.substr(1);
-
Create a rule with name, like:
loadPageRule
-
Add
Library Top
event forloadPageRule
-
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.
- Create a new rule with name:
fireGlobalMboxRule
- Add a custom event with eventType that we're dispatching, make sure you make it globally by checking
any element
option
- Add
Add Params to All Mboxes
action -> with paramviewName == %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 });
- 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