To Launch or not to Launch?
Adobe Launch is beautifully built, and as a web developer in charge of tagging management at a retail org, I’ve had a lot of success using it. But one of the challenges I faced was getting all my tags (especially event-triggered tags) to fire at the correct times on my SPA site.
After a little bit of digging, I found a solution, and now I want to share. The site I work on is built with Angular, and I want to help people understand how they can handle events in Adobe Launch in this framework or in other SPA frameworks (as well as teach some other important aspects of Launch).
If you’re familiar with Adobe Launch, feel free to skip the introduction (just jump to the “Implementing Event Triggers with Launch in an Angular SPA” section). Otherwise, there’s some information to familiarize you with the tag management solution.
Why the switch from DTM?
DTM was a beautiful system when it was made 10 years ago, but since then the whole SPA-based architecture came into play and DTM wasn’t doing a very good job.
Case in point: if you want to use DTM in an SPA framework, you have to configure a lot of waits. So for example, you’d be looking for hash change and then you’d say, “Ok, wait half a second” and hope everything will have loaded by then. That’s terrible. It’s just clunky. With Launch, you can avoid relying on waits, which is what I’m going to show here.
1. Setting Up Adobe Launch
Adobe Launch is a relatively intuitive solution, but before I jump into the weeds I want to give a quick summary of how to set yourself up in the TMS.
Setting up an environment
Setting up an environment in Launch is a little different from DTM—in DTM there was just staging and production. In Launch we now have the ability to define environments as we see fit, and approve and publish to them separately. Awesome!
At Orvis (the company I work for), I have three environments set up in Adobe Launch. I’ve got my dev environment, which is what I use on my local host. I’ve also got a staging environment for testing and then I’ve got a production environment.
Adding an environment is simple. Press the button to add environment and give it a name. Select an adapter to include in your environment. Then click “Create” and Launch spits out the script file specific to that environment.
This part of the process should look familiar to anyone who has used DTM in the past, but there is a catch. With DTM, you only had two environments: staging and production. Your production script would be a
.js and then your staging would be something like
The difference in Launch is that you can’t do any of the hacks that you might have done where you would just add “-staging” for a < production environment. As each environment has a different id, they will need to be set individually in an environment-specific file.
main.ts I’m actually adding that script URL itself.
Where should you place the link to this launch script? In a non-SPA environment we would add it in the head code, but of course, it’s not super helpful because when you’re routing, that’s not going to be re-fired. I’m going to address this issue later as we consider how to push tags into the data layer.
Setting up adapters
By assigning an adapter to your environment you determine where Launch will deliver a build. The easiest way to set up an adapter is to have Adobe manage the hosting. Just give it a name and that’s it.
If you want to do a little more custom configuration, then you can manage it yourself. But for most purposes, Adobe’s hosting will work just fine.
Extensions are built by both Adobe and Adobe partners and are how you integrate different tools into Adobe Launch. Installing an extension is pretty straightforward—just visit the Extension Catalog and click Install. Then you’ll get an opportunity to configure the extension before you save it.
Each extension will have its own settings, but here are some of the extensions my company has integrated with Launch:
As soon as you install Launch the first time, you’re going to have the Core extension come up. It needs literally no configuration, so you can just leave it alone.
Experience Cloud ID Service
The Experience Cloud ID Service is Adobe’s new version of the marketing cloud ID service they used to have for DTM.
The extension only has a few variables you have to set up:
- Your Adobe organization ID
- Your tracking service. At Orvis we have custom tracking variables set up to include our domain. If we hadn’t customized, the variables might be something like orvis.adobe.com. Setting up custom tracking variables that include your domain is important because you can avoid having your analytics blocked when crossing domain boundaries (into an Adobe domain).
For example, an ad blocker may take exception to you doing a call to a different domain like Adobe’s, so that’s why you would set up these custom tracking variables.
To set up Adobe Analytics, you input your report suites under development, staging and/or production.
Under the General dropdown, I don’t have to change anything except for the tracking servers because we have custom servers at Orvis.
You have the option of including global variables, but I don’t know how you’d have anything useful at the point of setting up the tool, unless maybe you have something foundational-based. I do have some global variables like page name and page path set up, but these are going to be overwritten by the side rules we will create later.
There are also settings for link tracking, cookies and Adobe Audience Manager, but I haven’t done anything with that yet, so I’m not going to speak to them here.
Configuring Adobe Target is also relatively straightforward. You have the following settings you can adjust:
- Client code
- Organization ID
- Global mbox name
- Server name
- Cross Domain (enabled or disabled)
- Timeout (ms)
Just drop in the correct values and you’re good to go. I personally only adjusted the ones I bolded above.
2. Implementing Event Triggers with Launch in an Angular SPA
Now let’s start getting into something a little bit more exciting: how to fire an event trigger in Launch for an SPA architecture.
But first, something very important we need to remember, and the goal of this walkthrough: You don’t want to fire any events until after Launch has loaded. If you fire events before then, Launch won’t be able to see them. So you’ll lose data.
Even though Launch loads pretty quickly during the initial SPA load (on navigating to the site initially), there’s a big chance that the site will start triggering events before Launch has successfully loaded.
We’re going to solve for that and keep from losing data.
Pushing your tags into the data layer
How hard is it to do this? Actually not that hard.
At the top of the
index.html file, I create the empty
digitalData layer and within it the events object, if they are not already created.
Here is how I push an event into this event collection. First I fire a tag call:
Which we will push into the
digitalData events object:
We can make this more robust still by implementing
requires to look for other events or whatnot before we do this push into the
digitalData events, but this is the core of it.
I have a number of tags that I fire and then later catch from Launch. Here is a non-exhaustive list.
- Template complete (I know the type of page I am on)
- Taxonomy loaded (I know the categorization of my page, ie Womens → Shirts)
- Data Layer loaded
I will also have optional ones for certain types of pages
All of these are pushed into this
window['digitalData'].events which will trigger rules in Launch.
And that’s it on the front-end coding end! By pushing the events themselves into the data layer, we can conserve the triggers until after Launch has loaded.
Setting up an event listener for the event triggers
Once we have set up Launch with Environments, Adapters and Extensions, everything else is either a Rule (event) or a Data Element (variable). The second part of the setup above is to make a rule that will turn the events above into
_satellite.track calls. By doing it this way we have ensured that no tracking calls are missed, because they are sitting in this array waiting for Launch to load and start doing things with them.
So I have a rule set up on page load like so:
This will load and define a function on events.push. So while before we would happily push events and they would sit there, we are now redefining it to do a
_satellite.track when it receives a push call. It will finally go through all events already in queue and re-push them to do this for our queued items.
I believe this to be a very solid methodology over the basic implementation path of just firing
_satellite.track, which would require Launch had loaded before firing events.
In an asynchronous site, unfortunately you can’t expect that to be the case. In fact, when I load a website for the first time (not when I route), I can almost guarantee I’ll be tracking events before Launch is loaded. But as we’ve just seen, that’s totally avoidable. Plus, because we’ve defined what the push function is, as more data comes in from the front end, it moves into Launch without any problems.
I’m sure that smarter people than me will come up with better ways of doing this, but that is our way, and I find that this works very well. Once I’ve got that particular piece hooked up, capturing the actual data is very easy.
3. Setting Up Rules in Adobe Launch
Once we’ve successfully set up our
digitalData events to fire tracking, we can use those events in the If-Then statements of Launch’s Rules. Rules use If-Then statements to determine when certain actions should be taken and where your data should be sent. With a non-SPA site we would have just used page top or bottom but now we will use these events to trigger Analytics, Target or any other tagging needs we might have.
Say for example we wanted to catch the event
taxComplete and fire a rule based on that tag. To capture that event is very simple with Launch, and I love the way Adobe has set up this feature. All I do is:
- Add or open a rule
- Add or edit an event for that rule
- Choose the Core extension
- Select Direct Call
- Give the event a name
- Provide the event identifier (
and bada-bing, bada-boom, this rule will fire when the
taxComplete identifier is called. Then just define which actions you want to take and you’re golden.
For example, when my
taxComplete event fires, I want to add parameters to my global mbox in Adobe Target and in turn fire my global mbox. Setting up these actions is pretty straightforward:
- Click the + icon in the Actions section of the rule configuration
- Choose the extension you want to work with
- Select the action type
Adobe Core Actions
The Core Extension allows you to run custom code as an action. Any of your normal tags will go through that.
Adobe Target Actions
Adobe Target gives you six different options, a couple of which are asynchronous actions:
- Load Target
- Load Target Async
- Add Params to All Mboxes
- Add Params to Global Mbox
- Fire Global Mbox
- Fire Global Mbox Async
The async calls are all marked as deprecated, so don’t use them. You want to load Target early in the page (I loaded it in my “initial load” rule). So in this case I don’t need to load it again, I just need to add params to the global mbox and then fire the global mbox.
Obvious point: you don’t want to fire the global mbox too many times. If you feel like you’re going to continue adding parameters to it, you’re going to want to fire the global mbox at a later time.
You can use conditions to apply the above methodology for more specific pages. For example, I might want to not fire Target on
taxComplete for a product page, as I will need some additional info. I can still populate the params in this
taxComplete but I can fire the global mbox when the more expensive product call comes back.
To do this, I would make a condition on the rule, and put a requirement that I have a data element populated from the
digitalData layer for firing it.
Each Tool Works a Little Different
Each extension works a little differently in Adobe Launch. Some you have to initialize, and some you don’t. Core, Experience Cloud ID and Adobe Analytics automatically initialize. Some you have to set variables (like Target, the Experience Cloud ID and Adobe Analytics). And some you have to effectively send a beacon or fire the mbox (Target and Analytics).
On the product detail page I only set the variables for Adobe Analytics, but I don’t send the beacon. In the case of Adobe Analytics, you want to make sure that everything else has fired first before sending a beacon. So I have a separate rule with these conditions with a higher order (goes last) that sends the beacon. That way I’m not sending Analytics data more than once, which could really mess up your bounce rates.
4. Logging with Adobe Launch
It might seem silly to want to talk about logging, since some people have been using this forever. But I’m a little behind the curve and have just gotten into this, and I love it.
With Adobe Launch on each individual page I can view which rules I’m qualifying for and which I’m not. And this is only visible to me—my customers can’t see it.
To view this, all I have to do is go into the browser developer tools console and set
_satellite.setDebug(true);. When I reload, I’ll see all of the rules being set, and all rules not being set.
And if I don’t qualify for a rule, it tells me why, so I can troubleshoot any errors that I have.
I can also choose to log additional information to keep me on track. I personally will use this to track things like data events firing. I just use that
satellite.logger.log and it’s safe cross browser and not customer facing.
The logger may not be the fanciest feature, but I just wanted to mention it as a great way of debugging what you’ve got going on.
5. Upstream Resources
For this last bit, I’m going to show you something that caused me endless problems until I figured it out. It might be super obvious, but it wasn’t obvious to me so I am including it.
As I was setting up my dev environment to get my first Launch implementation going, I had been working on it for a few days, and it just started giving me build failures. I looked into the issue, and saw that all the stuff I had added to the environment previously was gone. I was able to find the most recent things I had added, but everything else was missing.
Up until this point I hadn’t had the need to publish the changes to higher level environments. What I discovered was that the work I had lost should have been captured under Upstream Resources.
Upstream Resources is the way Launch lists resources that have been pushed to a higher environment like Staging and Production, and it uses this as a baseline for the Add All Changed Resources.
As I hadn’t published, there was no upstream. And the list of what had changed had somehow been lost over the days by Launch. It just arbitrarily said, “Eh! You don’t need that now anyway.” So I had to manually add everything back in. Hundreds of items. One by one.
Thankfully I was able to recover what was lost by doing this, and it only cost me about 20 minutes. Until it did it again, and then a third time. I contacted support and they said they were working on a fix for that, without telling me the root of the problem, that if I published to an environment I wasn’t using yet anyway, I would have an upstream and my impact would be vastly lessened.
So word to the wise: when you’re working, every so often submit and approve your work up to, say, staging or something. That will make it an upstream, and all that stuff is saved.
Transitioning to Adobe Launch
I’m still in the process of fully switching over to Adobe Launch, but I’ve been very impressed by what I’ve seen thus far. Making this type of transition is tough, but well worth the change. Having a tag governance solution like ObservePoint has made a big difference as well—their audits makes discovering and documenting tags much easier. You can try a sample audit of your website to see how it works.
About the AuthorLinkedIn More Content by Marten vanZwietering