Single Page App (SPA) Visual Experience Composer
In 蜜豆视频 Target, the Visual Experience Composer (VEC) gives marketers a do-it-yourself capability to create activities and personalize experiences that can be dynamically delivered on traditional Multi Page Applications via 蜜豆视频 Target鈥檚 global mbox. However, this relies on retrieving offers on page-load or subsequent server calls, which introduces latency, as shown in the diagram below. This approach does not work well with Single Page Applications (SPAs) because it degrades the user experience and application performance.
With the newest release, we now introduce the VEC for SPAs. The VEC for SPAs enables marketers to create tests and personalize content on SPAs in a do-it-yourself fashion without continuous development dependencies. The VEC can be used to create A/B Test and Experience Targeting (XT) activities on popular frameworks, such as React and Angular.
蜜豆视频 Target Views and Single Page Applications
The 蜜豆视频 Target VEC for SPAs takes advantage of a new concept called Views: a logical group of visual elements that together make up an SPA experience. A SPA can, therefore, be considered as transitioning through views, instead of URLs, based on user interactions. A View can typically represent a whole site or grouped visual elements within a site.
To explain further about what Views are, let鈥檚 navigate this hypothetical online e-commerce site implemented in React and explore some example Views. Click the links below to open this site in a new browser tab.
Link: Home Site
When we navigate to the home site, we can immediately see a hero image that promotes an Easter sale as well as the newest products selling on the site. In this case, a View can be defined as the entire home site. This is handy to note as we will expand on this more in the Implementing 蜜豆视频 Target Views section below.
Link: Product Site
As we become more interested in the products, we decide to click the Products link. Similar to the home site, the entirety of the products site can be defined as a View. We can name this View 鈥減roducts鈥 just like the path name in /developer/ashop-react-demo/at-js/#/products
.
In the beginning of this section, we defined Views as the whole site or even a group of visual elements on the site. As shown above, the four products shown on the site can also be grouped and considered as a View. If we wanted to name this View, we can name it 鈥減roducts鈥.
We decide to click on the Load More button to explore more products on the site. The website URL does not change in this case. But a View here can represent only the second row of products shown above. The View name can be called 鈥淧RODUCTS-PAGE-2鈥.
Link: Checkout
Because we liked some products shown on the site, we decided to buy a couple. Now, on the checkout site we are given some options to choose normal delivery or express delivery. Because a View can be any group of visual elements on a site, we can name this 鈥淰iew Delivery Preferences鈥.
Furthermore, the Views concept can be extended much further than this. If marketers want to personalize content on the site depending on which delivery preference is selected, a View can be created for each delivery preference. In this case, when we select Normal Delivery, the View can be named 鈥淣ormal Delivery鈥. If Express Delivery is selected, the View can be named 鈥淓xpress Delivery鈥.
Now, marketers might want to run an A/B Test to see whether changing the color from blue to red when Express Delivery is selected can boost conversions as opposed to keeping the button color blue for both delivery options.
Implementing 蜜豆视频 Target Views
Now that we have covered what 蜜豆视频 Target Views are, we can leverage this concept in Target to empower marketers to run A/B and XT tests on SPAs via the VEC. This will require a one-time developer setup. Let鈥檚 go through the steps to set this up.
-
Install at.js 2.x.
First, we need to install at.js 2.x. This version of at.js was developed with SPAs in mind. Previous versions of at.js and do not support 蜜豆视频 Target Views and the VEC for SPA.
Download the at.js 2.x via the 蜜豆视频 Target UI located in Administration > Implementation. at.js 2.x can also be deployed via tags in 蜜豆视频 Experience Platform. However, the 蜜豆视频 Target extensions are not currently up to date and supported.
-
Implement at.js 2.x鈥檚 newest function: triggerView() on your sites.
After defining the Views of your SPA where you want to run an A/B or XT test, implement at.js 2.x鈥檚
triggerView()
function with the Views passed in as a parameter. This allows marketers to use the VEC to design and run the A/B and XT tests for those Views defined. If thetriggerView()
function is not defined for those Views, the VEC will not detect the Views and thus marketers cannot use the VEC to design and run A/B and XT tests.adobe.target.triggerView(viewName, options)
table 0-row-5 1-row-5 2-row-5 3-row-5 Parameter Type Required? Validation Description viewName String Yes 1. No trailing spaces.
2. Cannot be empty.
3. View name should be unique for all pages.
4. Warning: View name should not start or end with 鈥/
鈥. This is because the customer would generally extract the View name from URL path. For us, 鈥渉ome鈥 and 鈥/home
鈥 are different.
5. Warning: Same view should not be consecutively triggered multiple times with the{page: true}
option.Pass in any name as a string type that you want to represent your View. This View name displays in the Modifications panel of the VEC for marketers to create actions and run their A/B and XT activities. options Object No options > page Boolean No TRUE: Default value of page is true. When page=true
, notifications will be sent to the Edge servers for incrementing impression count.
FALSE: Whenpage=false
, notifications will not be sent for incrementing impression count. This should be used when you want to only re-render a component on a page with an offer.Now let鈥檚 go through some example use cases on how to invoke the
triggerView()
function in React for our hypothetical e-commerce SPA:Link: Home Site
As marketers, if we want to run A/B tests on the whole home site, then we might want to name the view 鈥渉ome鈥 that can be extracted from the URL:
code language-javascript function targetView() { var viewName = window.location.hash; // or use window.location.pathName if router works on path and not hash viewName = viewName || 'home'; // view name cannot be empty // Sanitize viewName to get rid of any trailing symbols derived from URL if (viewName.startsWith('#') || viewName.startsWith('/')) { viewName = viewName.substr(1); } // Validate if the Target Libraries are available on your website if (typeof adobe != 'undefined' && adobe.target && typeof adobe.target.triggerView === 'function') { adobe.target.triggerView(viewName); } } // react router v4 const history = syncHistoryWithStore(createBrowserHistory(), store); history.listen(targetView); // react router v3 <Router history={hashHistory} onUpdate={targetView} >
Link: Products Site
Now, let鈥檚 look at an example that is a little bit more complicated. Let鈥檚 say as marketers, we would like to personalize the second row of the products by changing the price label color to red after a user clicked on the Load More button.
code language-javascript function targetView(viewName) { // Validate if the Target Libraries are available on your website if (typeof adobe != 'undefined' && adobe.target && typeof adobe.target.triggerView === 'function') { adobe.target.triggerView(viewName); } } class Products extends Component { render() { return ( <button type="button" onClick={this.handleLoadMoreClicked}>Load more</button> ); } handleLoadMoreClicked() { var page = this.state.page + 1; // assuming page number is derived from component's state this.setState({page: page}); targetView('PRODUCTS-PAGE-' + page); } }
Link: Checkout
If marketers want to personalize content on the site depending on which delivery preference is selected, a View can be created for each delivery preference. In this case, when we select Normal Delivery, the View can be named 鈥淣ormal Delivery鈥. If Express Delivery is selected, the View can be named 鈥淓xpress Delivery鈥.
Now, marketers might want to run an A/B test to see whether changing the color from blue to red when Express Delivery is selected can boost conversions as opposed to keeping the button color blue for both delivery options.
code language-javascript function targetView(viewName) { // Validate if the Target Libraries are available on your website if (typeof adobe != 'undefined' && adobe.target && typeof adobe.target.triggerView === 'function') { adobe.target.triggerView(viewName); } } class Checkout extends Component { render() { return ( <div onChange={this.onDeliveryPreferenceChanged}> <label> <input type="radio" id="normal" name="deliveryPreference" value={"Normal Delivery"} defaultChecked={true}/> <span> Normal Delivery (7-10 business days)</span> </label> <label> <input type="radio" id="express" name="deliveryPreference" value={"Express Delivery"}/> <span> Express Delivery* (2-3 business days)</span> </label> </div> ); } onDeliveryPreferenceChanged(evt) { var selectedPreferenceValue = evt.target.value; targetView(selectedPreferenceValue); } }
-
Launch A/B or XT activities via the VEC.
When
adobe.target.triggerView()
is implemented on your SPA with View names passed in as parameters, the VEC will be able to detect these views and allow users to create actions and modifications for their A/B or XT activities.note note NOTE The VEC for SPAs is really the same VEC that you use on regular web pages, but some additional capabilities are available when you open a single page app with triggerView()
implemented.
There are two major improvements to the Modifications panel and Actions for the VEC that allow the VEC to work well with SPAs.
Modifications Panel
The Modifications panel, as shown below, captures the actions created for a particular view. Notice that all actions for a View are grouped under that View.
Actions
Clicking an action highlights the element on the site where this action will be applied. Each VEC action created under a View has the following icons, as shown below: Information, Edit, Clone, Move, and Delete.
The following table describes each action:
Note: After a clone operation is made, you need to navigate to the View in the VEC via Browse to see whether the cloned action was a valid operation. If the action cannot be applied to the View, you will see an error.
Page Load Event 鈥 any actions corresponding to the page load event are applied on the initial page load of your web application.
Note After a move operation is made, you need to navigate to the View in the VEC via Browse to see whether the move was a valid operation. If the action cannot be applied to the View, you will see an error
Example 1
Let鈥檚 refer to the example above where we created a Home view. Our goal is two-fold for this view:
- Change the Add to Cart and the Like button to a lighter blue color. This should be in a 鈥淧age Load鈥 because we are changing components of the header.
- Change the 鈥淟atest Products for 2019鈥 label to 鈥淗ottest Products for 2019鈥 with the text color changed to purple.
To execute these goals, in the VEC, click Compose and apply those changes on the Home view.
Example 2
Let鈥檚 refer to the example above where we created a PRODUCTS-PAGE-2 view. Our goal is to change the 鈥淧rice鈥 label to 鈥淪ale Price鈥 with the label color as red.
- Click Browse, then click the Products link at the header.
- Click Load More once to get to the second row of products.
- Click Compose.
- Apply actions to change the text label to 鈥淪ale Price鈥 and the color to red.
Example 3
Lastly, as mentioned before, Views can be defined at a granular level. Views can be a state or even an option from a radio button. Previously we have created Views as CHECKOUT-EXPRESS and CHECKOUT-NORMAL. Our goal is to change the button color to red for the CHECKOUT-EXPRESS view.
- Click Browse.
- Add couple of products to the cart.
- Click the cart icon at the top right corner.
- Click Checkout your Order.
- Click on the Express Delivery radio button.
- Click Compose.
- Change the 鈥淧ay鈥 button to read 鈥淐omplete the Order鈥 button and change the color to red.
triggerView()
function is triggered when the Express Delivery radio button is selected and this is only when VEC knows that there is a View to show in the modification panel.Deep dive into at.js and SPAs
How can I retrieve views for the latest audience data hydrated by actions after the initial page load on my SPA?
The typical workflow of at.js 2.x is when your site loads, all of your views and actions are cached so that subsequent user actions on your site won鈥檛 trigger server calls to retrieve offers. If you want to retrieve views depending on the most up-to-date profile data that might have been updated depending on subsequent user actions, you can call getOffers()
and applyOffers()
with the latest audience user or profile data passed.
For example, consider that you are a telecom company and you have an SPA that uses at.js 2.x. As a business, you want to achieve the following objectives:
- For a logged out or anonymous user, show the latest company promotion, such as showing a 鈥淔irst month free鈥 hero offer on
http://www.telecom.com/home
. - For a logged in user, show an upgrade promotional offer for users whose contracts are coming up, such as 鈥淵ou are eligible for a free phone!鈥 on
http://www.telecom.com/loggedIn/home
.
Now, your developers name views and call triggerView()
in the following manner:
- For
http://www.telecom.com/home
the view name is 鈥淟ogged Out Home鈥triggerView("Logged Out Home")
is invoked.
- For
http://www.telecom.com/loggedIn/home
the view name is 鈥淟ogged In Home鈥triggerView("Logged In Home")
is invoked on route change.
Your marketers then run the following A/B activities through the VEC:
- A/B activity with the 鈥淔irst Month Free鈥 offer for audiences with the parameter 鈥
loggedIn= false
鈥 to be shown inhttp://www.telecom.com/home
, where the view name is Logged Out Home. - A/B activity with the 鈥淵ou are eligible for a free phone!鈥 offer for audiences with the parameter 鈥
loggedIn=true
鈥 to be shown inhttp://www.telecom.com/loggedIn/home
, where the view name is Logged In Hero Offer.
Now, lets consider this user flow:
- An anonymous logged-out user lands on your page.
- Because you are using at.js 2.x, you pass in the parameter 鈥
loggedIn = false
鈥 on page-load to retrieve all views present in active activities that qualify for when the audience has parameter 鈥loggedIn = false
鈥. - at.js 2.x then retrieves the Logged Out Home view and action to show the 鈥淔irst Month Free鈥 offer and stores it in cache.
- When
triggerView("Logged Out Home")
is invoked, the 鈥淔irst Month Free鈥 offer is retrieved from cache and the offer is shown without a server call. - The user now clicks 鈥淟og in鈥 and provides his or her credentials.
- Because your website is an SPA, you do not conduct a full page load and instead route your user to
http://www.telecom.com/loggedIn/home
.
Now, here is the problem. The user logs in and we encounter triggerView("Logged In Home")
because we placed this code on route change. This tells at.js 2.x to retrieve the view and actions from cache, but the only view that exists in cache is Logged Out Home.
So, how can we then retrieve our Logged In View and show the 鈥淵ou are eligible for a free phone!鈥 offer? And since all subsequent actions on your site will be from a logged-in-user perspective, how can you make sure all subsequent actions result in personalized offers for logged-in users?
You can use the new getOffers()
and applyOffers()
functions supported in at.js 2.x:
adobe.target.getOffers({
request: {
prefetch: {
"views": [
{
"parameters": {
"loggedIn": true
},
}
]
},
});
Pass the response of getOffers()
to applyOffers()
and now all views and actions associated with 鈥渓oggedIn = true鈥 will update the at.js cache.
In other words, at.js 2.x supports a way to retrieve views, actions, and offers with the most up-to-date audience data in an on-demand fashion.
Does at.js 2.x support A4T for Single Page Applications?
Yes, at.js 2.x supports A4T for SPA via the triggerView()
function given that you have implemented 蜜豆视频 Analytics and the Experience Cloud Visitor ID Service. See the diagram below with step-by-step descriptions.
triggerView()
is called in the SPA to render a view and apply actions to modify visual elements associated to the view.{page: false}
to the triggerView()
function so that impression counting is not inflated when a view is triggered multiple times for a component that re-renders constantly. For example:adobe.target.triggerView("PRODUCTS-PAGE-2", {page:false})
Supported activities
in A/B Test and Experience Targeting (XT) activities
If we installed at.js 2.x and implemented triggerView()
on our sites, how do we run Auto-Target A/B activities because the SPA VEC doesn鈥檛 support Auto-Target?
If you want to use Auto-Target A/B activities, you can move all of your actions to be executed on Page Load Event in the VEC. Hover over each action, and click the Move to Page Load Event button. After this is done, in the next step, you can select Auto-Target for the traffic allocation method.
Supported integrations
Supported features supported-features
Page Delivery settings for the SPA VEC page-delivery-settings
Page Delivery settings let you configure rules to determine when a Target activity should qualify and execute for an audience.
To access the Page Delivery options from within the VEC鈥檚 three-part guided activity-creation workflow, from the Experiences step, click Configure (the gear icon) > Page Delivery.
For example, as defined by the Page Delivery settings shown above, a Target activity qualifies and executes when a visitor lands directly on https://www.adobe.com
or when a visitor lands on any URL that contains https://www.adobe.com/products
. This works perfectly for any multi-page application in which every interaction with the page invokes a page reload, for which at.js retrieves the activities that qualify for the URL that the user navigates to.
However, because SPAs work differently, the Page Delivery settings must be configured in a way that allows all actions to be applied to the Views as defined in the SPA VEC activity.
Example use-case
Consider this example use-case:
The following changes were made:
- Changed the background color in the Home view, which is located under the URL: /developer/ashop-react-demo/at-js/#/.
- Changed the button color in the Products view, which is located under the URL: /developer/ashop-react-demo/at-js/#/products.
With the example above in mind, what would happen when we configure Page Delivery settings to only include: /developer/ashop-react-demo/at-js/#/ in an SPA with at.js 2.x?
The following illustration shows the Target Flow - Page Load request in at.js 2.x:
User Journey #1
- A user navigates directly to /developer/ashop-react-demo/at-js/#/.
- at.js 2.x makes a query to the Edge to see if any activity needs to execute for the URL: /developer/ashop-react-demo/at-js/#/.
- In step 6, the Target Edge returns the actions for the Home and Products view so that they are cached within the browser.
Result: The user sees the green background color in the Home view. When the user then navigates to /developer/ashop-react-demo/at-js/#/products, the blue background color of the button is seen because the action is cached in the browser under the Products view.
Note: The user navigating to /developer/ashop-react-demo/at-js/#/products did not trigger a page load.
User Journey #2
- A user navigates directly to /developer/ashop-react-demo/at-js/#/products.
- at.js 2.x makes a query to the Edge to see if any activity needs to execute for the URL: /developer/ashop-react-demo/at-js/#/products.
- There are no activities qualified for /developer/ashop-react-demo/at-js/#/products.
- Because there are no activities qualified, there are no actions and Views to be cached for at.js 2.x to trigger from.
Result: Even if you have defined triggerView()
for the Products View and made an action to the Products View through the SPA VEC, you will not see the expected action since you did not create a rule that included /developer/ashop-react-demo/at-js/#/products in the Page Delivery settings.
Best Practice
You can see that managing the user journey can be quite difficult as users can land on any URL of your SPA and navigate to any other page. Therefore, it is best to specify a Page Delivery rule that includes the base URL so that it includes your entire SPA. In this way, you don鈥檛 need to think about all the different journeys and paths that a user might take to get to a page on which you want to show an A/B Test or Experience Targeting (XT) activity.
For example, in order to resolve the issue faced above, we can specify the base URL in the Page Delivery settings as such:
This ensures that wherever a visitor lands on the SPA and navigates to either the Home or Page View will see the actions applied.
Now, whenever you add an action to a View in the SPA VEC, we will show you the following pop-up message to remind you to think about the Page Delivery rules.
This message displays when you add the first action to a View for every new activity you create. This message helps ensure that everyone in your organization learns how to apply these Page Delivery rules correctly.
Training video: Using the VEC for SPAs in 蜜豆视频 Target
See for more information.