When configuring a click event in Adobe Experience Platform Launch, there is a setting that is commonly referred to as “link delay”.
This is a complex piece of functionality that is not well understood. Today I want to demystify this capability. I will explain what it is doing, potential issues that you’ll face, and some workarounds for those scenarios.
What it does
The first thing of note is the element definition. Link delay will only trigger at runtime if your defined selector is a link element (an <a> tag). It will do nothing for any other types of elements.
The next thing to know is what happens at runtime when you turn this on the link delay. When a click event is triggered on a link element that matches your selector definition, the Platform Launch runtime will:
- Call the event.preventDefault(); function - this has the impact of preventing the browser’s default action on the clicked element, which - since this is an <a> tag - prevents the browser from navigating off the page. You can read more about preventDefault() here (MDN Docs).
- Call the window.setTimeout() method with your specified timeout – This method causes the browser to wait for exactly the specified time before taking the next action. It is not intelligent. It isn’t a max timeout method that will move on quicker if it finishes something else. It pauses all processing on that thread until the specified time interval has passed, then it moves on to the next instruction. You can read more about the setTimeout() method here.
When we field customer questions or bug reports about link delay, there are a couple common themes that recur.
One common issue is poorly defined selectors where the link delay is triggering where the user does not intend it to. There are two variants of this:
- The selector was defined broadly so it triggers in too many places
- The selector was defined to trigger on a page element where page navigation is not the desired user behavior in the first place
One recent example I saw was a case where the page markup defined an <a> tag where the intended user behavior was not to navigate to a new page, but to pop a modal dialog for the user to interact with. When Launch applied link delay to this element, the observed behavior is that the modal dialog popped for 1 second (the timeout) and then the page navigated away before the user could interact with the modal.
If your selector was just defined too broadly, then your path to resolution is to make a more specific selector. If you’ve got link elements where navigation is not the desired user behavior, then you have two potential paths to resolution. You can either make a more specific selector so that it doesn’t trigger on that link, or you can change your page markup so that it doesn’t use a link, but uses something more appropriate for the scenario (like a button).
The other common issue revolves around the behavior of the setTimeout() method. It is a blunt instrument. It does not adjust based on the client device’s bandwidth or processing capabilities. It is ignorant of the workload that you are trying to execute while the timeout is counting down. And it directly affects the end-user experience. Users on fast devices with high bandwidth might wait much longer than is necessary. Users with slower devices or lower bandwidth might only execute half the workload you intended before the timeout is reached.
Unfortunately, there aren’t great workarounds for this, but there are a few things you can explore.
- Use the sendBeacon() API. If you are trying to send a request to some endpoint before the page navigates away, you can investigate using the sendBeacon() API (MDN Docs). For example, Adobe Analytics appMeasurement automatically uses this API for exit links, but also provides a variable called s.useBeacon that allows you to use it for any links. If you set this variable to true, then appMeasurement will send Analytics requests using the sendBeacon() API (more here). You can also use this in custom code and can talk to your extension providers to see if they support this as well.
- Minimize work payloads during the timeout. This is more of a tip than a workaround, but minimizing the amount of work you’re trying to achieve during the timeout will improve the chances that the workload will complete successfully. Reducing the number of rule actions - particularly custom code - in your workloads will help.
- Send on the next page. Instead of trying to get off a request before page navigation, we've seen some other users that will store the data in local storage and just send it on the next page.
Click events that have been copied over from DTM have a special issue all to themselves. This issue is really just a more specific variation on the Selector definition issue defined above.
Events in a browser are processed through three phases of (1) capturing, (2) target, and (3) bubbling. DTM captured events in the bubbling phase. This phase is the last of the three phases, so it was possible for website application code to prevent the event from reaching that phase (such as by calling event.stopPropagation() or event.stopImmediatePropagation()). As far as DTM was aware, these events never actually happened.
Platform Launch click handlers are processed during the capturing phase (first phase) specifically to avoid this issue. You can read more about this specific change and the reasons in Aaron Hardy’s excellent post on the Adobe Tech Blog. As a result, that the same user-defined selector on a click handler will trigger more often with Platform Launch than it would have with DTM.
Some users migrating from DTM to Platform Launch have found that their click handlers are attaching to more events than they used to and are leading to unexpected outcomes in their implementation. Where those click handlers also apply a link delay, the outcomes can be more obvious and have a larger effect on the end-user experience.
The solution is the same as the Selector definition above. In some circumstances, you can fix it by refining your selector to something more specific. In other cases you can change your page markup to use a different DOM element that isn’t a link.
Due to the lack of reliability in the link delay functionality and the availability of other options, Platform Launch still provides you with link delay functionality for backwards compatibility with DTM (as much as possible), but does not recommend it and no longer offers support for it.
For the most common use case if sending data before page navigation occurs, we recommend you take a long look at the sendBeacon() API to see if it meets your needs.