From e684e53cce84b06d7092f37fd91b10ab4d9dda8e Mon Sep 17 00:00:00 2001 From: Adeola Adeyemo Date: Tue, 3 Mar 2026 12:08:41 +0000 Subject: [PATCH 1/2] chore: add custom events to web component documentation Signed-off-by: Adeola Adeyemo --- docs/journeys/embedding.md | 6 ++ docs/journeys/web-components.md | 135 ++++++++++++++++++++++++-------- 2 files changed, 110 insertions(+), 31 deletions(-) diff --git a/docs/journeys/embedding.md b/docs/journeys/embedding.md index 0eb39060..f2badd9e 100644 --- a/docs/journeys/embedding.md +++ b/docs/journeys/embedding.md @@ -336,3 +336,9 @@ In this example, no `data-ep-` attributes are needed because the `__epilot.init( **Outcome** ![Embedding Multiple Outcome](../../static/img/journey-embed-outcome-multiple.gif) + +## Web Components Alternative + +If you're starting a new integration, consider using the [Web Component embed](./web-components) instead of iframes. Web Components render the Journey directly in your page using the Shadow DOM, offering better performance, accessibility, and tighter integration with your host application — no cross-frame messaging required. + +See the [Web Components documentation](./web-components) for the full setup guide, attribute reference, and event handling. diff --git a/docs/journeys/web-components.md b/docs/journeys/web-components.md index e0685403..9c4983c1 100644 --- a/docs/journeys/web-components.md +++ b/docs/journeys/web-components.md @@ -132,34 +132,6 @@ Interactive examples are available at [Storybook Examples](https://embed.journey ::: -## Limitations - -### Single instance per page - -Only one `` element is supported per page. Placing multiple instances on the same page is not supported and may lead to unexpected behavior. - -To load a different Journey, update the attributes on the existing element rather than adding a new one: - -```html title="Single element" - - - - - -``` - -If you need multiple Journeys visible simultaneously, use the [iframe embedding](./embedding) approach instead. - ## Context Data Use the `context-data` attribute to pass additional key-value pairs to the Journey. This data is included with the submission and can be used for tracking, attribution, or pre-configuring behavior. @@ -176,6 +148,8 @@ The value must be a JSON-encoded string. Only **string** and **numeric** values Numeric values are coerced to strings internally. +The Journey also automatically picks up **URL search query parameters** from the host page and includes them as context data. For example, if the page URL is `https://example.com/energy?utm_source=google&campaign=summer`, the `utm_source` and `campaign` values will be included in the context data automatically. Values passed explicitly via the `context-data` attribute take precedence over query parameters when keys overlap. + ## Data Injection Data injection allows you to pre-fill Journey fields with data and optionally start from a specific step. This is useful when your website has already collected some information (e.g. a product selection or address) and you want to carry it into the Journey. @@ -272,9 +246,106 @@ You can also call the `refresh()` method on the element to force a re-render: document.querySelector('epilot-journey').refresh() ``` +## Events + +The `` Web Component dispatches custom events on the `window` object that you can listen for. These events correspond to the iframe `postMessage` events used by the [iframe embed script](./embedding), translated into standard DOM custom events. + +### Event Reference + +| iframe postMessage Event | Web Component Custom Event | Description | +| ------------------------------ | ------------------------------- | ---------------------------------------------------- | +| `EPILOT/JOURNEY_LOADED` | `epilot:journey-loaded` | The Journey has finished loading. | +| `EPILOT/EXIT_FULLSCREEN` | `epilot:exit-fullscreen` | The Journey exited full-screen mode. | +| `EPILOT/ENTER_FULLSCREEN` | `epilot:enter-fullscreen` | The Journey entered full-screen mode. | +| `EPILOT/CLOSE_JOURNEY` | `epilot:close-journey` | The user closed the Journey. | +| `EPILOT/FORM_EVENT` | `epilot:form-event` | A form-level event occurred (e.g. submission). | +| `EPILOT/USER_EVENT/PAGE_VIEW` | `epilot:user-event:page-view` | The user navigated to a new step. | +| `EPILOT/USER_EVENT/PROGRESS` | `epilot:user-event:progress` | The user made progress in the Journey. | +| `ExitFullScreen` | `exitfullscreen` | Legacy event for exiting full-screen mode. | + +### Listening for Events + +```javascript title="Listening for journey events" +// React when the journey finishes loading +window.addEventListener('epilot:journey-loaded', () => { + console.log('Journey has loaded!') +}) + +// React when the user navigates to a new step +window.addEventListener('epilot:user-event:page-view', (event) => { + console.log('User navigated to a new step', event.detail) +}) +``` + +### Example: Showing a Skeleton Loader + +A common use case is to display a loading skeleton while the Journey loads, then reveal the Journey once it's ready. You can listen for the `epilot:user-event:page-view` event (for inline mode) or `epilot:journey-loaded` (for full-screen mode) to know when the Journey is ready to be shown. + +```html title="Skeleton loader with web component" + +
+
+
+
+
+
+ + + + + +``` + +## Limitations + +### Single instance per page + +Only one `` element is supported per page. Placing multiple instances on the same page is not supported and may lead to unexpected behavior. + +To load a different Journey, update the attributes on the existing element rather than adding a new one: + +```html title="Single element" + + + + + +``` + +If you need multiple Journeys visible simultaneously, use the [iframe embedding](./embedding) approach instead. + ## Content-Security-Policy (CSP) -If you don’t have Content-Security-Policy defined for your pages, you can skip this. If you have but can temporarily disable to perform the this test, go for that. Otherwise, please ensure you update your policy to allow the below +If you don't have Content-Security-Policy defined for your pages, you can skip this. If you have but can temporarily disable to perform the this test, go for that. Otherwise, please ensure you update your policy to allow the below ```text title="Minimum CSP for Web Components" script-src https://journey.epilot.io; @@ -288,7 +359,7 @@ If you don’t have Content-Security-Policy defined for your pages, you can skip :::tip -These rules are subject to change as we’re rolling out new features and web components themselves. Depending on your Journey setups, you might also need to give additional permissions in case you’re using third-party apps or apps of your own. +These rules are subject to change as we're rolling out new features and web components themselves. Depending on your Journey setups, you might also need to give additional permissions in case you're using third-party apps or apps of your own. ::: @@ -325,6 +396,8 @@ If you are currently embedding Journeys using iframes with the `__epilot` embed + > ``` -3. **Update CSP rules** — the same epilot domain rules apply. See [Content-Security-Policy](./content-security-policy). +3. **Migrate event listeners** — replace `__epilot.on()` calls with standard `window.addEventListener()` using the new custom event names. See the [Events](#events) section for the full mapping. + +4. **Update CSP rules** — the same epilot domain rules apply. See [Content-Security-Policy](./content-security-policy). The attribute names on the Web Component map directly to the options you previously passed to `__epilot.init()`, converted to kebab-case (e.g. `topBar` becomes `top-bar`, `scrollToTop` becomes `scroll-to-top`). From 91028994e5a80c1a1fc1aaab207abc4da79629db Mon Sep 17 00:00:00 2001 From: Adeola Adeyemo Date: Tue, 3 Mar 2026 13:35:43 +0000 Subject: [PATCH 2/2] chore: update events naming Signed-off-by: Adeola Adeyemo --- docs/journeys/web-components.md | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/journeys/web-components.md b/docs/journeys/web-components.md index 9c4983c1..e57ed46c 100644 --- a/docs/journeys/web-components.md +++ b/docs/journeys/web-components.md @@ -248,38 +248,38 @@ document.querySelector('epilot-journey').refresh() ## Events -The `` Web Component dispatches custom events on the `window` object that you can listen for. These events correspond to the iframe `postMessage` events used by the [iframe embed script](./embedding), translated into standard DOM custom events. +The `` Web Component dispatches custom events on the `window` object that you can listen for. The event names are the same as the iframe `postMessage` events used by the [iframe embed script](./embedding), so you can use the same event names regardless of the embedding method. ### Event Reference -| iframe postMessage Event | Web Component Custom Event | Description | -| ------------------------------ | ------------------------------- | ---------------------------------------------------- | -| `EPILOT/JOURNEY_LOADED` | `epilot:journey-loaded` | The Journey has finished loading. | -| `EPILOT/EXIT_FULLSCREEN` | `epilot:exit-fullscreen` | The Journey exited full-screen mode. | -| `EPILOT/ENTER_FULLSCREEN` | `epilot:enter-fullscreen` | The Journey entered full-screen mode. | -| `EPILOT/CLOSE_JOURNEY` | `epilot:close-journey` | The user closed the Journey. | -| `EPILOT/FORM_EVENT` | `epilot:form-event` | A form-level event occurred (e.g. submission). | -| `EPILOT/USER_EVENT/PAGE_VIEW` | `epilot:user-event:page-view` | The user navigated to a new step. | -| `EPILOT/USER_EVENT/PROGRESS` | `epilot:user-event:progress` | The user made progress in the Journey. | -| `ExitFullScreen` | `exitfullscreen` | Legacy event for exiting full-screen mode. | +| Event | Description | +| ------------------------------ | ---------------------------------------------------- | +| `EPILOT/JOURNEY_LOADED` | The Journey has finished loading. | +| `EPILOT/EXIT_FULLSCREEN` | The Journey exited full-screen mode. | +| `EPILOT/ENTER_FULLSCREEN` | The Journey entered full-screen mode. | +| `EPILOT/CLOSE_JOURNEY` | The user closed the Journey. | +| `EPILOT/FORM_EVENT` | A form-level event occurred (e.g. submission). | +| `EPILOT/USER_EVENT/PAGE_VIEW` | The user navigated to a new step. | +| `EPILOT/USER_EVENT/PROGRESS` | The user made progress in the Journey. | +| `ExitFullScreen` | Legacy event for exiting full-screen mode. | ### Listening for Events ```javascript title="Listening for journey events" // React when the journey finishes loading -window.addEventListener('epilot:journey-loaded', () => { +window.addEventListener('EPILOT/JOURNEY_LOADED', () => { console.log('Journey has loaded!') }) // React when the user navigates to a new step -window.addEventListener('epilot:user-event:page-view', (event) => { +window.addEventListener('EPILOT/USER_EVENT/PAGE_VIEW', (event) => { console.log('User navigated to a new step', event.detail) }) ``` ### Example: Showing a Skeleton Loader -A common use case is to display a loading skeleton while the Journey loads, then reveal the Journey once it's ready. You can listen for the `epilot:user-event:page-view` event (for inline mode) or `epilot:journey-loaded` (for full-screen mode) to know when the Journey is ready to be shown. +A common use case is to display a loading skeleton while the Journey loads, then reveal the Journey once it's ready. You can listen for the `EPILOT/USER_EVENT/PAGE_VIEW` event (for inline mode) or `EPILOT/JOURNEY_LOADED` (for full-screen mode) to know when the Journey is ready to be shown. ```html title="Skeleton loader with web component" @@ -300,7 +300,7 @@ A common use case is to display a loading skeleton while the Journey loads, then > ``` @@ -396,7 +396,7 @@ If you are currently embedding Journeys using iframes with the `__epilot` embed + > ``` -3. **Migrate event listeners** — replace `__epilot.on()` calls with standard `window.addEventListener()` using the new custom event names. See the [Events](#events) section for the full mapping. +3. **Migrate event listeners** — replace `__epilot.on()` calls with standard `window.addEventListener()`. The event names are the same as the iframe postMessage events, so no renaming is needed. See the [Events](#events) section for the full list. 4. **Update CSP rules** — the same epilot domain rules apply. See [Content-Security-Policy](./content-security-policy).