Module 04 · Tags by Adobe Launch

Where your
tracking lives.

Launch is the deployment surface. The AppMeasurement code from module 03 doesn't appear by magic — it is built, hosted, and triggered by Launch. This module is a complete tour.

Reading55 min
LabRule simulator
DifficultyCore
Pre-reqModules 01–03

1 · What Launch is, mechanically

Launch is a code generator. You configure a property in Adobe's UI; Launch compiles that configuration into a single JavaScript bundle and hosts it on Adobe's CDN. You add a <script src="…launch-EN12345.min.js"> tag to your website's head, and that bundle takes over from there: it loads AppMeasurement, evaluates your rules, sets variables, and fires hits.

┌──────────────────┐      compile       ┌────────────────────────────┐
│  Launch UI       │  ───────────────→  │  launch-ENxxxx.min.js      │
│  (your config)   │   build & publish │  hosted on assets.adobedtm  │
└──────────────────┘                    └────────────────────────────┘
        │                                          │
        │  rules, extensions, data elements        │  loaded by <script> on every page
        ▼                                          ▼
        no code on your servers                    runs in the browser

The valuable insight: Launch is not doing the tracking. It is choreographing it. AppMeasurement still does the work — Launch decides when, with what data, and to which environment.

2 · Properties

A property in Launch is a container. It represents one digital surface — a website, a sub-domain, a mobile app. Inside a property live:

  • Extensions — installable feature packages.
  • Data elements — named values you can reference everywhere.
  • Rules — when/what/then triggers.
  • Environments — dev, staging, production.
  • Libraries — versioned bundles of the above, published into environments.

How many properties?

A common debate. The general rule:

  • One per distinct digital experience. Your customer-facing site is one property. Your account portal is another. They don't share code, they shouldn't share a property.
  • Multi-domain sites under one brand → one property. If example.com and shop.example.com share design, share users, and share a measurement plan, they share a property.
  • Localised variants → one property. A site that runs in 30 languages does not need 30 properties. Use one property and key off a language data element.

3 · Extensions — the building blocks

An extension is a package of functionality. Some are made by Adobe, some by partners, some by you. Installing one gives you new events, conditions, actions, and data element types in the rule editor.

The four extensions you will install on day one

ExtensionWhat it provides
CoreBuilt-in. Page-load events, click events, custom code action. You cannot remove it.
Adobe AnalyticsThe s object. Configuration UI. The "Set Variables" and "Send Beacon" actions. Required for any AA work.
Experience Cloud ID ServiceThe ECID library. Drops the visitor cookie before AA fires. Install this before the AA extension or your visitor count will be wrong.
Adobe Client Data LayerIf you use ACDL (and you should — see module 02), install this to get event-bus rules.

The order matters

Extensions load in dependency order, but on the page, the ID Service must respond before AppMeasurement fires its first hit. Otherwise the hit lands without an ECID and shows up as a brand-new visitor. The Adobe Analytics extension knows to wait for the ID Service — but only if you've installed and configured the ID Service. This is a common silent failure.

4 · Data elements — your named variables

A data element is a reusable getter for one value. Instead of writing the same digitalData.page.pageInfo.pageName path in 40 rules, you define one data element called "Page Name" and reference it as %Page Name%.

Launch ships with these data element types out of the box:

TypeWhat it readsWhen to use
Data LayerA dotted path into your data layer object.Default choice. Use this whenever you can.
CookieValue of a named cookie.For values stored in cookies (consent, AB variant).
JavaScript VariableA global property.window.somethingGlobal.
Local StorageKey from localStorage.SPA state.
Query String ParameterA URL parameter.Campaign codes, search terms.
Page InfoThings like URL, hostname, referrer.Built-in convenience.
Custom CodeArbitrary JavaScript.When none of the above apply. Use sparingly.

The custom code data element

This is your escape hatch. A Custom Code data element runs the JavaScript you write and returns whatever you return from it.

// Data Element: "Logged-In Status"
// Type: Custom Code
var d = window.digitalData;
if (!d || !d.user || !d.user[0]) return "anonymous";
var status = d.user[0].profile?.[0]?.profileInfo?.returningStatus;
return status || "anonymous";

Two things to remember:

  • You must return the value. Without an explicit return, the data element resolves to undefined.
  • This code runs every time a rule reads the data element. Keep it fast. Don't fetch network resources, don't loop over thousands of DOM nodes.

Default value, force lower case, clean text

Every data element has these three options. Use them.

  • Default value — what to return if your getter returns null, undefined, or empty. Set this to a sentinel like "(not set)" so you can find missing data in reports rather than wondering why a chart is empty.
  • Force lower case — Adobe is case-sensitive. "Telescopes" and "telescopes" are two values in your eVar1 report. Force lower case on dimensions and this whole class of problem disappears.
  • Clean text — trims whitespace, collapses internal whitespace. Free hygiene.

5 · Rules — the heart of Launch

A rule is a sentence: "When [event] and if [conditions], then do [actions]." Every meaningful interaction in your implementation is one or more rules.

┌─── EVENTS ────────┐   ┌─── CONDITIONS ───┐   ┌─── ACTIONS ───────┐
│ Page loaded       │ → │ Path is /product │ → │ Set s.pageName    │
│ Click on selector │   │ User is loggedIn │   │ Set s.eVar4       │
│ DataLayer event   │   │ Cookie X present │   │ Fire s.t()        │
│ Custom event      │   │ Tag has value Y  │   │ Run custom code   │
└───────────────────┘   └──────────────────┘   └───────────────────┘
       any of                  all of                  sequence

5.1 Events

An event is the trigger. Examples from the Core extension:

  • Library Loaded — when Launch itself loaded. Earliest possible moment.
  • Page Top — synchronously, before DOMContentLoaded.
  • Page Bottom — synchronously, after the page's body.
  • DOM Ready — when the DOM is parsed.
  • Window Loaded — when every resource has loaded. Late.
  • Click — on a CSS selector you specify.
  • Form Submit — when a form posts.
  • Direct Call — fired explicitly via _satellite.track("event-name").

The Direct Call event is your most important extension point. The application calls _satellite.track("checkout:order-completed", { orderId: "12345" }), and your rule fires with access to that data. This is how SPA tracking works (module 07).

5.2 Conditions

Conditions narrow the trigger. "Page Loaded" fires on every page; "Page Loaded AND path matches /product" fires only on product pages.

Useful built-in conditions: URL match, browser, screen resolution, cookie presence, data element comparison, custom code (returning truthy/falsy).

5.3 Actions

The work. The "Adobe Analytics — Set Variables" action gives you a UI for assigning s.pageName, every eVar, every prop, every event. The "Adobe Analytics — Send Beacon" action then chooses between s.t() (page view) or s.tl() (link).

You can also drop into Core — Custom Code for an arbitrary JavaScript block. The variable event in that scope is the event payload (useful for direct calls).

// Custom code action inside a "Cart Item Added" rule
var item = event.detail; // payload from _satellite.track("cart:item:added", { ... })

s.linkTrackVars   = "events,products,eVar5";
s.linkTrackEvents = "scAdd";

s.events   = "scAdd";
s.products = item.category + ";" + item.sku + ";1;" + item.price;
s.eVar5    = item.sku;

s.tl(true, "o", "Cart · Item Added");

5.4 Rule ordering

Within a single event, rules execute in order priority (low first; default 50). This matters when one rule must set up state for another. Common pattern:

  • Order 10: "Set page-level variables" — runs first, sets s.pageName, s.channel, etc.
  • Order 50: "Page view send beacon" — fires the hit.
  • Order 90: "Clear variables" — resets s for the next page (SPAs).

6 · Libraries and environments

A library is a versioned bundle of selected extensions, data elements, and rules. You build it; Launch compiles it; you publish it to an environment.

EnvironmentPurpose
DevelopmentAuto-builds. Embed code lives on your dev/QA site. No approval needed.
StagingApproval required. Embed lives on your pre-production site.
ProductionApproval + publish required. Embed lives on production.

Each environment has its own embed code. The same Launch property serves three URLs. Your dev site loads the dev embed; your prod site loads the prod embed. Versioning is automatic — Launch keeps the history.

The library workflow

1. Edit       — change rules, data elements, extensions
2. Add        — drop your changed resources into a "Working Library"
3. Build      — compile the library; check the build log
4. Approve    — promote from Dev → Staging environment
5. QA on staging
6. Publish    — promote Staging → Production
7. (Roll back if needed — Launch keeps every previous build)

This is, in everything but the UI, a code-review workflow. Treat it like one: pull-requests in Launch should map to pull-requests in your application code. The two systems must agree.

7 · Deploying to your site

Two embed codes per environment:

<!-- Head — synchronous load (slows page; gives full coverage) -->
<script src="//assets.adobedtm.com/launch-EN12345-development.min.js"></script>

<!-- OR asynchronous (fast; risk of missing very-early hits) -->
<script src="//assets.adobedtm.com/launch-EN12345-development.min.js" async></script>

For a customer-facing site, prefer async. The synchronous embed will visibly delay your page render in field conditions. The async embed risks a couple of milliseconds where clicks aren't yet tracked — but in practice you tolerate this in exchange for the speed win.

For an internal tool where speed is irrelevant and accuracy is paramount, prefer sync.

The page-bottom problem

Launch's "Page Bottom" event needs you to place a small JS snippet at the actual bottom of your HTML body. Few teams do this. When the event doesn't fire, rules tied to it silently fail. If a "Page Bottom" rule isn't running, this is almost always why.

8 · Patterns and pitfalls

8.1 — The "set everything in one rule" anti-pattern

It is tempting to have a single rule called "All Page Views" that switches on URL path and sets every variable for every page type. Don't. The rule becomes unreadable, conditions get nested four deep, and one mistake breaks tracking site-wide.

Better: one rule per page type (Home, PDP, PLP, Checkout, Confirmation). Each is small, each is testable, and each can be turned off independently when a page is being redesigned.

8.2 — The "global rule" pattern

The opposite extreme works well: one low-priority rule that sets universal variables (login status, language, AB-test variant) on every page, then page-type rules that add their specifics. The two rules together build the hit; the second relies on the first having run.

8.3 — Naming conventions

Adopt one before you have ten rules. Suggested:

Rules:           [Hit type] · [Trigger] · [Page or context]
                 "Page View · DOM Ready · Product Detail"
                 "Link · Click · Mega Nav"

Data Elements:   [Source]: [Path or purpose]
                 "DL: page.pageName"
                 "DL: product[0].sku"
                 "Cookie: consent.statistics"
                 "JS: User Status"

8.4 — Use the Debug menu

In the browser console, type _satellite.setDebug(true). Launch then logs every rule it considers — fired, skipped, blocked by conditions, with detail. This is your single most valuable QA tool inside Launch itself; we revisit it in module 09.

8.5 — Watch the build size

Every extension you install adds weight to the Launch bundle. A bloated bundle slows page load, which lowers conversion, which is the metric you exist to measure. Audit installed extensions yearly; remove what isn't used.

9 · Checkpoint

By the end of this module you should be able to:

  • Describe what a Launch property contains and why a single site has exactly one.
  • Define the difference between an extension and a rule.
  • Name three kinds of data element and when to use each.
  • Build the "When / If / Then" of a rule on paper for a known scenario.
  • Explain why the Experience Cloud ID Service extension must load before AA.
  • Choose between sync and async embed.

Next, in module 05, we go deep on eVars, props, and events — the variables that carry all the analytical weight.