Events between the UI and the SDK
This page explains the events that happen between the SDK, user interface and the outside website. These events are important and can be used to build custom functionality, such as:
- Allowing user to enter a private room if they are logged in
- Collecting collectables that can be turned in for various rewards
- Showing a specific UI screen when the user reaches a specific point in the experience
And much more!
Getting Started
In order to see the events that are being sent from the SDK and the experience, you can set the debug
parameter to be true, when embedding the experience via the SDK, like so:
<script>
window.emperiaAsyncInit = function () {
emperia.init({
id: "experience-root",
experience_url: "https://experience.emperiavr.com/example/experience/experience.html",
ui_url: "https://ui.emperiavr.com/Standard-UI/Production/2.0.0/static/",
attach_ui: true,
debug: true
});
};
</script>
You can read more about the available parameters in the SDK page. You can also view the events being sent in this testing URL.
The next time you open up a page, you should see events being logged inside the console view, like so:
Event Structure
There are set events that get sent by default with each exprience, however you also have the option to add your own custom events through the Unreal Engine plugin. You can read about adding custom actions and models here.
Below is a table explaining the structure of the event.
Value | Possible values | Description | |
name | uiReady | uiReady, OpenInfo, OpenCustomModel, OpenPDP | Events with this name are sent when the UI has been initialized and is ready. |
type | SDKEvent | SDKEvent, experienceEvent | Explains where the event came from. |
data | null | Any data you want to send, for example, ‘554235’, “message”, “prop” | Allows you to send any data that you wish with the event. This can be used to pass the product ID that you want to open the PDP for. |
market | gb | gb, es, it | Defines the market of the experience. This can be used for changing the market on the UI. |
locale | en | en, it, es | Defines the language of the experience. |
organization_id | “” | 8fcb067a-2099-430c-829d-ca401d5c5db6 | The organisation ID this experience belongs to. This is currently optional, but will become mandatory in the future. |
event (deprecated) | experience_event | experience_event | This was used to inform the SDK where the events are coming from. |
Event invocation
Certain events are emitted when a certain action happens within the SDK or the experience. Below is a table explaining when each event is invoked.
Event Name | Description |
uiReady | Gets called when the user interface is ready and initialized. |
OpenInfo | Gets called when the user hovers, clicks or the mouse leaves the element. |
OpenCustomModel | Gets called when the user hovers, clicks or the mouse leaves the element. |
OpenPDP | Gets called when the user hovers, clicks or the mouse leaves the element. |
How does the SDK talk to Standard-UI
- Now when the dispatcher dispatches an event
dispatch({ name: "uiReady" })
, the UI on the other end is listening to it like this,
useEffect(() => {
const eventListener = (event: Event) => {
const interceptedEvent = event as CustomEvent;
const eventType = interceptedEvent.detail.name as keyof typeof eventMap;
const eventData = interceptedEvent.detail.data;
if (eventMap[eventType]) {
eventMap[eventType](eventData);
}
};
window.emperia?.events?.addEventListener('fromExperience', eventListener);
return () => {
window.emperia?.events?.removeEventListener('fromExperience', eventListener);
};
}, []);
- There are bunch of events that the SDK can send to the UI defined as.
const eventMap = {
uiReady: () => onUIReady(),
openWelcome: () => openWelcomeModal(),
openInstructions: () => openInstructionsModal(),
openProduct: (productVariantId: string) => openProductModal(productVariantId),
openInfo: (infoModalId: string) => openInfoModal(infoModalId),
updateLanguage: () => updateLanguage(),
};
Each of these is pretty self explanatory but for example you want to open the product Modal with a product with an id exampleId123
you would dispatch the following event from the sdk,
dispatch({ name: "openProduct", data:{ productVariantId: 'exampleId123' } });
How does the Standard-UI talk to SDK
Now why would we want the Ui layer to talk to SDK ? Well there are more than one reasons, first is to cater any kind of tracking of analytics, secondly to communicate any change in data layer i.e. change Language of the data object being sued by the UI
The data object used by UI to populate static content, such as overlay elements etc is populated by the SDK itself when initializing data elements.
- When this listener is activated from the SDK
listen("fromUserInterface")
the UI can then call the SDK in such way,
window.emperia.events.dispatchEvent(
new CustomEvent('fromUserInterface', { detail: { name: 'changeLanguage', locale: lang } }),
);
As you can see its dispatching an event with name fromUserInterface
with the name changeLanguage
and the locale it needs to be changed to.
- While the SDK is listening to this, this is how it decides which function to invoke based on incoming event request,
const detectEvent = (incomingEvent: CustomEvent) => {
const miscMap = window.emperia.misc;
const ecommerceMap = window.emperia.ecommerce;
const gamificationMap = window.emperia.gamification;
const integrationMap = window.emperia.integration;
const languageMap = window.emperia.language;
const eventType = incomingEvent.detail.name;
const eventData = incomingEvent.detail.analyticObject;
const locale = incomingEvent.detail.locale;
if (miscMap[eventType]) {
miscMap[eventType](eventData);
} else if (ecommerceMap[eventType]) {
ecommerceMap[eventType](eventData);
} else if (gamificationMap[eventType]) {
gamificationMap[eventType](eventData);
} else if (integrationMap[eventType]) {
integrationMap[eventType](eventData);
} else if (languageMap[eventType]) {
languageMap[eventType](locale);
}
const params = new URLSearchParams(location.search);
if (params.get("debug") == null) return;
console.log(
`%c Recieved ${incomingEvent.detail.name} with ${JSON.stringify(
incomingEvent
)} object.`,
"color: #7fb7e2"
);
};
const listenerEventMap = {
fromUserInterface: detectEvent,
};
export const listen = (name: string) => {
window.emperia?.events?.addEventListener(
name,
listenerEventMap[name as keyof typeof listenerEventMap]
);
};
- The function we wanted to invoke is called
changeLanguage
and lives in side thelanguageMap
as,
export const Language = {
'changeLanguage': (locale: string) => changeLanguage(locale)
}
And that is how the UI communicated to the SDK.
Use cases
You can read more about how these events can be used to communicate between the experience and the website on this page.
Help & Support
If you have questions, suggestions, or feature requests, please join the Official Emperia Discord channel!
You can find support here through private support tickets or general conversation. You will also have the opportunity to showcase your work and chat with like-minded individuals across industries using Creator Tools, Unreal Engine, those creating immersive experiences, and more!
If you prefer, you can also reach out to us via email.