Repository navigation
feat: add ExO event builder to the Experiences SDK - #203
Conversation
There was a problem hiding this comment.
Why does this live in the core package direclty and not something optimization-scoped? Would make it easier to define granular ownership later on and ensure clearer boundaries between concerns.
There was a problem hiding this comment.
We've discussed about this before if should we organize the structure/modules first, then introduce optimization features, or we make it progress now and organize later on.
We came up with an agreement to have it in core scope from now, but in a near future we'll may have optimization-core or something.
There was a problem hiding this comment.
A builder instance would be added to the SDK runtime instance (when it exists) so if we end up adding a shared runtime class to Core then we would continue to colocate this here. The runtime would need to be in Core (or Node/Web, depending) and not in a separate Optimization package because it would not only affect personalization functionality but also improve general Experiences SDK DX.
There was a problem hiding this comment.
That does not make sense to me. Why would code need to be co-located in the same physical package to use it?
That being said, I'm fine to defer this if that was the agreed mode of operation for now.
There was a problem hiding this comment.
Why would you not want to colocate it? I'd rather not go digging for code far from where I intend to use it, especially if it won't be used directly elsewhere. It's also a bit small for its own package.
Summary
This PR adds event-builder functionality to the Experiences SDK, including support for ExO view, click, and hover events.
It also introduces
@contentful/optimization-api-client, Zod Mini, andes-toolkitas dependencies of the core package.Related Jira ticket: NT-3534
Description
The new
EventBuilderlives in@contentful/experiences-sdk-coreand is available through the React, Svelte, and Angular SDKs. It providesbuildExoView,buildExoClick, andbuildExoHover, while retaining support for flag-view, identify, page-view, and custom track events.The builder centralizes universal event metadata, context enrichment, timestamps, consent, campaign attribution, validation, and API payload construction. Tests verify ExO schema compatibility, runtime validation, context providers, campaign extraction, and the retained event methods.
This change introduces
@contentful/optimization-api-clientas a runtime dependency of the Experiences SDK core package. The API client provides the authoritative event schemas, event types, friendly validation errors, and shared logging behavior. Reusing these contracts prevents the Experiences SDK from maintaining copies that could drift from the Optimization APIs.The API client does not provide the Experiences event builder itself.
EventBuilderremains an Experiences SDK integration layer that translates runtime Experiences data into API-compatible event structures. Because the framework SDKs depend on core, the API client becomes a transitive dependency of the React, Svelte, and Angular packages.Zod Mini is important because event inputs can be assembled from arbitrary runtime data, where TypeScript types provide no protection. Validation at the builder boundary prevents malformed events from reaching the API and provides useful errors to consumers.
es-toolkitis used to merge default page context with event-specific properties. A tested structured merge avoids losing nested runtime context and removes the need to maintain custom merge behavior inside the SDK.Motivation and Context
The Experiences SDK needs a shared integration layer for constructing events emitted from rendered ExO entities. Without runtime validation, malformed or incomplete event data could be emitted silently, especially for JavaScript consumers or values derived from application and CMS state.
This implementation keeps event construction environment-neutral while leaving room for future web-specific context collection.
Related Jira ticket: NT-3534
PR Checklist
CONTRIBUTING.mdfile