Migration › Knowledge Base › Data-layer design
Data-layer design
Your data layer is the menu the waiter reads from. The Web SDK can only serve what the menu describes clearly, so a migration is the rare moment to look hard at that menu.
The Web SDK is agnostic about your data layer; it does not require the Adobe Client Data Layer. The meaningful distinction is shape. A computed-state layer (a digitalData object) is a photograph painted once at load; fine for traditional pages, but stale the instant a single-page-app changes route[35][T6]. An event-driven layer (ACDL or a Google dataLayer) is a live broadcast[T2], the app pushes a message the moment something happens, so a beacon can't fire before its data exists.
Quality matters as much as shape: values decoupled from the DOM, one source of truth per value, stable names and consistent types, populated before they're needed.
For your migration: keep your existing layer and map it, ripping out a working data layer is cost with little benefit. But fix the cheap wins while you're touching every field, and on a SPA, prefer an event-driven signal so route changes never fire on stale data.
Keep and map your existing data layer. On SPAs, fire on an event-driven "view ready" signal, never on a raw route change.
The menu the waiter reads
Your data layer is the menu the Web SDK reads from; it can only serve what the menu describes clearly. The migration is the rare moment you get to look hard at that menu, so it's worth understanding what "good" looks like even though you'll keep your existing layer.
Computed-state vs event-driven
A computed-state layer (a digitalData object) is a photograph: painted once at page load. Perfect for traditional, full-page-load sites. But on a single-page app the photo is stale the instant the route changes, the object still describes the previous view. An event-driven layer (the Adobe Client Data Layer or a Google dataLayer) is a live broadcast: the app pushes a message the moment something happens, so a tag can't fire before its data exists. For SPAs and heavy async, that's the structural fix.
A quality ladder
| Bad | flat, DOM-scraped values, a CSS change silently breaks tracking |
| Better | nested and namespaced, page.pageInfo.pageName |
| Enterprise | a governed, versioned spec, populated server-side at a known point |
Design principles, and the pragmatic call
Decouple values from the DOM; one source of truth per value; stable names and consistent types; populate before you need it. But don't turn the migration into a data-layer rebuild, keep your working layer and map it, fixing the cheap wins while you're touching every field. On SPAs specifically, trigger your Send Event on an event-driven "view ready" push, never on a raw history change, or you'll ship stale payloads.