Expand my Community achievements bar.

Using Target on a SPA in Web SDK

Avatar

Employee

6/7/24

What is a Single Page Application (SPA)? A SPA is a web app implementation that loads only a single web document, and then updates the body content of that single document via JavaScript APIs when different content is to be shown.

A great place to start is Vadym’s previous post on SPAs and Target.

This is an excellent article that explains the workings of a SPA. This page will focus on what is new regarding Web SDK and SPAs.

Web SDK is a client-side JavaScript library that allows customers of Adobe Experience Cloud to interact with both Adobe applications and third-party services through the Adobe Experience Platform Edge Network.

In the past, Target was designed to work with a multi-page application. On every page load, Target would fire and do any content replacement that needed to happen. The key was that the page would fully reload. With SPAs, we needed a way to render personalization experiences without reloading the page.

Both AT.js and Web SDK depend on the concept of a view. While triggerView was the method for AT.js, the sendEvent is used for Web SDK. Target must be notified of each view as early as possible. As mentioned in the previous article, for React, componentDidMount is a good indicator of the start of the view. One way of triggering the view, would be to publish an event in componentDidMount and use Tags to listen for the event and trigger a sendEvent with the view name.

Here is an example of a ‘home’ event getting triggered in React code:

Picture1.png

Here is an example of a Tags rule that listens for that event and fires a sendEvent with the view name taken from the event:

Picture2.png

Here is the definition of the page XDM that references the event detail containing the view name:

Picture3.png

This one rule can be used for all views with the view name passed in the event.

On the first sendEvent, similar to a page load request, all the activities setup on views will be prefetched and saved in cache. Below is an example:

Picture4.png

What this shows is that there are three views getting prefetched into cache: about, about2 and home. While they have been prefetched, they won’t get applied until the user visits each view.

Now we have an example of what we see in the network tab when a sendEvent with a view name is executed:

Picture5.png

This shows the changes defined in the activity for the “home” view getting applied. It is not requesting anything from the server, just a notification of proposition display.

With SPAs via Web SDK there is the same challenges of Virtual DOM and persisting the personalized content. One way to re-render the content would be to use a similar event approach as defined above. In React, you could trigger a similar event in the componentDidUpdate method. Below is some code to accomplish this:

Here is the original sendEvent on the home view to render the content:

 

Picture6.png

 

If the Virtual DOM updates the page, you can trigger the below to re-apply the changes:

Picture7.png

 

No call is made to the server, it just re-applies the modifications that were in cache.

There is one more subtle point to make regarding SPAs. A user may do an action like logging in or clicking on a button on a popup that makes a change to the dataLayer and may cause the user to now qualify for a different activity. This is where a sendEvent call with an additional parameter can be made to refresh the prefetched cache and apply the modification.

 For example, take this:

 Picture8.png

 

This could be used to invoke a Target activity where it is looking for a parameter of expA = yes. Say you had another activity that was looking for expB = yes. If you re-fired the above call, just changing the parameter to expB, you would not qualify for the second activity, and nothing would happen. Notice the slight difference below:

 

Picture9.png

 

This parameter: personalization: { defaultPersonalizationEnabled: true } allows the cache to be refreshed, user to qualify and the modifications to be applied.

Here’s an example that could tie it all together. A telecom store wants to offer a discount on a phone case on the checkout page for 50% of the traffic for a certain model phone. You would open the site in the Visual Experience Composer (VEC) of Target and make your way to the checkout page where you would add your DOM changes for the discount. When a user comes to the site and is qualified into the alternate experience, the code for the discount will be pre-fetched on page load. As the user makes their way to checkout, the view will be triggered and the changes applied offering a discount to the user.

Hopefully this gives you a good idea of how to use Target and Web SDK for SPA personalization.

Here is some additional information.

Also, here is some good Web SDK info.

***

 

 

 

Are you looking to optimize your website's performance and drive conversions?

Look no further than Adobe - the industry leader in A/B testing. With more A/B tests under our belt than any other organization in the world, we have the expertise and knowledge to take your online presence to the next level. Adobe Target is unrivaled in the industry, and with Adobe Consulting, you can have access to this powerful tool and the expertise behind it. Don't miss out on the opportunity to unlock the full potential of your website. Contact us today and discover how Adobe can help your business thrive. If you would like to understand how Adobe can help your business reach out to Adobe Consulting Services

 

 

 

6 Comments

Avatar

Level 4

6/17/24

@Ron_Houseman  thank you for a very informative post - super helpful! I am having issues rendering experience on the subsequent SPA views. All propositions appear to be fetched correctly via eventType: "decisioning.propositionFetch". Although, the payload structure looks a bit different to what you have shown. 

Capture.PNG

 

Every view triggers the request below, but I can't render any experiences on the subsequent SPAs. Any advice would be very helpful. Thanks

 

alloy("sendEvent", {
    renderDecisions: true,
    xdm: {
      web: {
        webPageDetails: {
          viewName: window._dl.page_name,
        },
      },
    },
  });


 

Avatar

Employee

6/17/24

You've validated that your window._dl.page_name matches the view name?

Avatar

Level 4

6/17/24

@Ron_Houseman yes, have put it exactly as in the scope.

Capture 1.PNG

Can see changes applied in the browse / compose modes, but nothing is being rendered on the page. Analytics captures all the relevant values though. Screenshot from the experiment set up:

 

Capture 2.PNG

Avatar

Employee

6/17/24

What does the payload of the sendEvent where it tries to apply the changes look like for that view?

Avatar

Level 4

6/18/24

@Ron_Houseman here is what happens on the SPA transition.

 

propDisplay.PNG

Avatar

Level 4

6/18/24

@Ron_Houseman managed to resolve the issue. It is very interesting how experiment scopes are defined in the code...