Skip to main content
AEMEdge Delivery ServicesAdobe TargetAEPWeb SDK

How to Integrate Adobe Target with Edge Delivery Services Using Web SDK

A step-by-step technical breakdown of how EDS, AEP Edge Network, and Adobe Target work together to deliver real-time personalization — without touching the DOM.

9 min read

Adobe Edge Delivery Services (EDS) provides a fast, document-based web stack. Adobe Target offers A/B testing and personalization capabilities. Integrating these two systems requires understanding some specific architectural considerations. This guide covers the complete integration, from the AEP schema setup all the way to rendering personalized content in EDS blocks, explaining the reasoning behind each technical decision.

The actors in the system

Four components form the integration architecture:

Browser (EDS)  ←→  AEP Edge Network  ←→  Adobe Target
                        ↑
                    Datastream

The browser runs Alloy (Adobe Web SDK) within your EDS project. Alloy communicates with the AEP Edge Network through a Datastream, which routes events to the enabled services — including Adobe Target.

1. The XDM Schema — your data contract

Configure an XDM Schema in AEP as a formal data structure definition. This functions as a contract: declared fields can be transmitted; undeclared fields are rejected.

Class selection: use the Experience Event class, since Alloy transmits events (time-based occurrences: page views, clicks, interactions) rather than static profile data.

The schema defines structure only — it doesn't process data by itself. Runtime data flows through Alloy.

A minimal schema includes the standard XDM fields (eventType, web.URL, web.name, timestamp) plus the custom fields your implementation needs — such as userCountry for geographic personalization.

2. The Datastream — the central router

The Datastream is the most critical configuration object in this architecture. It serves as the AEP entry point and determines which Adobe services receive event data.

Datastream: "name-of-your-datastream"
├── Receives events from Alloy (Web SDK)
├── Validates against your XDM Schema
└── Forwards to configured services:
    └── Adobe Target ✅ Enabled

When Alloy transmits an event that includes a datastreamId, the Edge Network locates that datastream, confirms Target is enabled, and forwards the event to Target for activity evaluation.

This routing layer enables modularity: you can add AEP Profile, Analytics, or Audience Manager to the same datastream later without modifying any frontend code.

3. The Target activity — personalization rules

Create an Experience Targeting (XT) activity in Adobe Target using the Form-based Experience Composer. Unlike the Visual Experience Composer (VEC), the form-based composer works with named locations called mboxes instead of CSS selectors.

Why this matters: EDS constructs the DOM programmatically, which makes VEC-style DOM manipulation unreliable. Form-based composition returning JSON offers is the correct pattern.

Activity: "Hero Background Personalization"
Location: hero-background
├── Rule 1: Spain (ES)
│   └── Returns Experience B:
│       { "hero": { "backgroundImage": "/images/hero-bg-es.jpg" } }
└── Rule 2: All Visitors (fallback)
    └── Returns Experience A:
        { "hero": { "backgroundImage": "/images/hero-bg-default.jpg" } }

Target evaluates the rules sequentially and returns the first match. The location value (hero-background) is what connects the activity to your JavaScript. Target returns raw JSON — no HTML, no CSS. Your EDS block decides how to apply it.

4. Alloy (Web SDK) — the messenger

Alloy is Adobe's JavaScript library bridging the browser and the Edge Network. Initialize it in your EDS project's alloy-init.js:

await window.alloy('configure', {
  datastreamId: 'your-datastreamId',
  orgId: 'your-orgId@AdobeOrg',
  edgeDomain: 'edge.adobedc.net',
});

After configuration, Alloy can transmit events via sendEvent. The configuration step specifies which datastream to use. Since EDS loads scripts asynchronously, you'll need a readiness flag (window.alloy_configured = true) that blocks can wait on before firing events.

5. The complete request flow

Here's the exact sequence when a user lands on the page:

  1. User opens /landing-page in their browser.
  2. scripts.js runs initAlloy() — loads Alloy from the CDN, configures it with the datastreamId, sets window.alloy_configured = true.
  3. EDS decorates the Hero block. hero.js calls sendPageViewEvent(['hero-background']) and waits for Alloy readiness via waitForAlloy().
  4. Alloy sends a POST to edge.adobedc.net/ee/v2/interact with the XDM event payload and the decisionScopes: ['hero-background'] query.
  5. The Edge Network identifies the datastream, confirms Target is enabled, and forwards the request to Target with the requested scope.
  6. Target evaluates the activity. The user's IP resolves to Spain → Rule 1 matches → Experience B returns.
  7. The Edge Network returns the response to Alloy as a propositions array.
  8. hero.js parses the proposition content, extracts the backgroundImage value, and renders the hero block with that image.
  9. notifyDisplay() sends a decisioning.propositionDisplay event back to AEP so Target records the impression and populates the activity reports.

6. Why decisionScopes is non-negotiable

This is the most frequent mistake in EDS + Target integrations. Without explicitly requesting a scope, Target evaluates only the global __view__ scope — which corresponds to VEC activities. Form-based activities remain invisible to Target unless requested by name.

Without scope — Target returns nothing:

window.alloy('sendEvent', {
  renderDecisions: false,
  xdm: { /* ... */ }
})
// → propositions: []

With scope — Target returns your activity:

window.alloy('sendEvent', {
  renderDecisions: false,
  decisionScopes: ['hero-background'],
  xdm: { /* ... */ }
})
// → propositions: [{ scope: 'hero-background', items: [...] }]

7. Why renderDecisions: false

Target can apply decisions through two methods:

  • renderDecisions: true — Target modifies the DOM directly. Designed for VEC activities where Target injects CSS or HTML. This breaks in EDS because EDS controls the DOM construction process.
  • renderDecisions: false — Target returns decisions as JSON. Your JavaScript determines what to do with them. This is the correct approach for EDS: you maintain control over how and when personalization is applied.

8. Closing the reporting loop with notifyDisplay()

The notifyDisplay() call is frequently overlooked, but it's essential for meaningful Target activity reports.

sendEvent (request)      → Target knows someone asked for hero-background
notifyDisplay (impression) → Target knows the experience was actually rendered
(future) sendEvent click → Target knows if the user converted

Conclusion

This integration pattern — Datastream → form-based activity → decisionScopes → JSON propositions → manual DOM application — is the foundation for any serious personalization work in EDS. Once you understand the flow, adding more blocks, more activities, and more targeting rules becomes straightforward.