User Interface
This page describes the user interface, how it is built, and what is necessary to build your own user interface.
Please note that attaching a custom user interface is only allowed on PRO plans and above.
The user interface is a separate component from the virtual experience skeleton. There are multiple reasons for it:
- Allows swapping out user interfaces for different experiences.
- Allows independent development of the user interface.
- Allows developers to use the modern frameworks such as React, Vue and others to build their user interfaces.
The user interfaces that are built by us, and that are provided as the default UI, are built using Chakra and React, and npm as the package manager. It is built as a static package, hosted on a server and then served to users via the SDK.
QuickStart
In order to help your development process for building the user interface, we have built a repository that contains code to get you started. Please feel free to fork this repository and kickstart your development process!
Standard-UI
- a link to our Standard-UI repo, works out of the box.
Requirements
Choosing a framework
Before the user interface can be attached to the experience via a URL, the user interface needs to be prepared.
You can use any of the popular frameworks for UI development:
As long as the framework is able to output raw html, css, and javascript files, it will be compatible with the experiences.
Preparing styling
There are a couple of rules you need to follow to ensure that the user interface is being shown accurately, does not hide the experience, and follows good design principles, this applies to basically any component/UI item you build:
- Positioning: Since our UI layer and the Experience layer are two separate layers interconnected by the SDK, to show or make interactive UI on top of the experience, we can’t position elements just relatively / flexbox style.
- Our UI should always be positioned -
fixed/absolute
, but that is only reserved to the parent element of the component. Top / Left / Bottom / Right
should also be set to position a component correctly.Z Index
should also be set higher than 0 so it can be displayed correctly.- This is an example of a navbar component using Chakra-UI, in which we can see that even though the component is positioned to be fixed but has normal styles applied to the children inside:
- If you are using vanilla HTML / JS / CSS, the following would do the same
<Box
position="fixed"
top="0px"
width="100%"
height="50px"
display="flex"
justifyContent="space-between"
alignItems="center"
>
{children here}
</Box>
<div class="fixed-box">
<!-- children here -->
</div>
.fixed-box {
position: fixed;
top: 0px;
width: 100%;
height: 50px;
display: flex;
justify-content: space-between;
align-items: center;
}
Building the user interface
The user interface will be served statically, hence it needs to be built as HTML5, js and css files. Typically any of the above framework / libraries mentioned have a build command that usually generates static build files that one can use, like these below:
Since the SDK right now is configured to attach a main.js / main.css i.e. build files from a typical React / Vue / Angular app, there might be some caveats
- Vanilla JS Build: if your UI is purely built using Vanilla JS, Html and Css you would need to name your JS file like
main.js
, your css file likemain.css
and lastly yourindex.html
file or the file containing html should be placed on the same level as the SDK, i.e. wherever you’re initiating your experience using the SDK call. - Naming convention: You would have notice that we specifically mention files as
main.js
andmain.css
and that is because usually a library / framework app produces build files using a hash naming convention and since the sdk needs to already know the file names and is not editable, we can’t have it hashed, it would not be read by the sdk hence we in our predefined UI use a script to rename files while they are being deployed, using github actions.
The build needs to look something like this:
Best practices to follow
So to build user interfaces we follow some practices that makes it easier to keep track and understand chain of actions, following is a list of things we do:
- Keeping components segregated, for example: don't make every little thing part of the overlay, keep it simple and light.
- Building a component to do one and only defined feature and making it fully controllable.
- Avoid Overloading your entry point usually
App.tsx
in React for example, with a lot of state variables, instead use Zustand like libraries to share state and make it much more clean.
How to achieve performance
To achieve a good performance on your app so it has better Lighthouse report and google performance metrics, we recommend doing the following:
- Code Splitting: Making chunks of your js build files, essentially only loading the content for user that is needed when the page is loaded, usually called Lazy Loading in React.
- Optimizing Assets:
- Fonts: You should use font-face to load your custom fonts and if you do it asynchronously, it's even better as it would not block CSS from quickly loading.
- Images: Try using advanced formats like we use webp and it offers immense performance gains, same quality and way lesser size.
- Videos: Try keeping it simple with mp4 and the hack with videos is to have video dimensions according to the max dimensions of your Ui component, if. a box on UI has a max dimension of 400x500, there is no point in my video being 1000x1200, its unused size can be reduced.
Deploying the user interface
You can deploy the static user interface as a folder to any domain or service you wish to use. Some popular examples would be:
- S3, with Cloudfront as the CDN
- Azure Blob Storage, Azure CDN as the CDN
- Cloud Storage, Cloud CDN as the CDN
We highly recommend using a CDN to serve your assets, as that improves reliability, speed and performance of the assets that are being served.
The assets should be accessible via public URL, as they will be referenced inside the SDK like so:
"https://ui.emperiavr.com/Standard-UI/Production/2.0.0/static/"
Testing Locally
When you are ready to test the user interface locally and attach it to the experience, host the statically built user interface. Here’s some methods on how to host a static page on your machine:
- If you are using VSCode, you can use the Live Server extension to host your code
- With npm, npx, brew, you can try out the http-server package to host your code
If you want to test the UI as a standalone, since the UI is prepared in a way that it listens to events for actions from the SDK, you could call it from the JS Console in a browser like:
window.dispatchEvent(
new CustomEvent("fromExperience", {
detail: {
name:"uiReady",
},
})
);
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.