Create The App
Download the contact list app's starter zip file from here and unzip it into a working folder.
The unzipped content has the following folders and files:
File/Folder | Description |
---|---|
index.html | The default webpage to display |
Main.xmlui | The XMLUI app's entry point |
components | The folder with the app's XMLUI components (empty) |
resources | The folder with static app resources like images, logos, icons, etc. |
xmlui | The folder with the XMLUI framework's runtime and the emulated API |
mockApi.js | The service worker for emulated backend |
start.bat | The batch file to start the http-server utility (assumes Node.js is installed) on Windows |
start.sh | The bash script file to start the http-server utility (assumes Node.js is installed) on Mac and Linux |
Remember, you need a local web server to run the XMLUI app. Install the LTS version of Node.js on your machine (https://nodejs.org/en (opens in a new tab)), for you will use the http-server Node package to host the tutorial.
In your command prompt, select the downloaded sample's unzipped folder (with the cd command), and run start.bat
on Windows or start.sh
on Mac or Linux, which will start the web server and open your browser with the app.
Alternatively, you can start the webserver directly by issuing the npx -y http-server -o
command.
This is how the sample app should appear:

This app uses an emulated backend that persists data. XMLUI has a built-in emulation technology for this purpose.
The app is straightforward as it only contains one single markup file (Main.xmlui
) which acts as the entry point for an XMLUI app:
<App
layout="vertical-sticky"
name="Contact List Tutorial"
logo="resources/logo.svg"
logo-dark="resources/logo-dark.svg">
<AppHeader>
<H2>Contact Management</H2>
<SpaceFiller />
<ToneChangerButton />
</AppHeader>
<NavPanel>
<NavLink label="Home" to="/" />
</NavPanel>
<Pages>
<Page url="/">
Home
</Page>
</Pages>
<Footer>
Powered by XMLUI
</Footer>
</App>
The application uses the vertical-sticky
layout, which renders a vertical menu on the left side of the app and provides a sticky header and footer above and below the main content area. The name
property of App
defines the title to display in the browser tab.
The AppHeader
defines a title and allows a ToneChangerButton
to choose between light and dark themes.
The logo
and logo-dark
properties set the resource files to display a logo. If you omit them, the app will not show a logo.
Setting Up the Scenario
The sample app works with a list of contacts stored in a database with two tables, contacts
and categories
. The latter one is a dictionary that associates an integer ID with a display name to describe contact categories like "Decision Maker," "Influencer," and others.
The structure of these tables is the following:
The contacts
table:
Field | Type | Description |
---|---|---|
id | integer | The unique identifier of the contact |
fullName | string | The contact's name |
categoryId | integer | Reference to the category ID of the contact |
comments | string | Additional information about the contact |
reviewDueDate | date | The date when the contact should be reviewed |
reviewCompleted | boolean | Indicates whether the review is completed |
The categories
table:
Field | Type | Description |
---|---|---|
id | integer | The unique identifier of the category |
name | string | The category's name |
color | string | The category's color |
Though storing something like "color" in a database may be an anti-pattern, we store category colors there for the sake of simplicity, and we use this information in this tutorial.
In this application, we assume that each contact's information is regularly reviewed by someone (for example, after a visit or a call). We store related data for each contact in the reviewDueDate
and reviewCompleted
fields. In the tutorial, you will use the information for filtering and grouping.
Creating Pages for the App
The default app uses a horizontal layout with a single menu item, Home. The initial version of the Contact List app will contain only two pages, one for a dashboard and another for listing contacts.
You can modify the default app structure in a few steps:
First, open the Main.xmlui
file in your text editor and change its contents to the following:
<App
layout="vertical-sticky"
name="Contact List Tutorial"
logo="resources/logo.svg"
logo-dark="resources/logo-dark.svg">
<AppHeader>
<H2>Contact Management</H2>
<SpaceFiller />
<ToneChangerButton />
</AppHeader>
<NavPanel>
<NavLink label="Dashboard" to="/" />
<NavLink label="Contacts" to="/contacts" />
</NavPanel>
<Pages>
<Page url="/">Dashboard</Page>
<Page url="/contacts">Contacts</Page>
</Pages>
<Footer>
Powered by XMLUI
</Footer>
</App>
Refresh the browser to see your changes. You should see a new navigation item in the side navigation panel:

Using an Emulated Backend
The app will use a backend to retrieve and store data. XMLUI provides a powerful tool, the API emulator, as part of the framework, which provides an in-browser backend.
Creating an emulated backend is not very complex but requires a different experience than leveraging web API endpoints. We provided this emulation with the contact list app for you; you just use it.
Test the emulated backend by adding code that triggers invoking an endpoint. Replace the Page
tag with the /contacts
URL with this one:
<!-- Omitted -->
<Page url="/contacts">
<DataSource id="message" url="/api/test" />
<Text>{message.value}</Text>
</Page>
<!-- Omitted -->
The framework considers text wrapped between curly braces an expression. Instead of displaying the literal value, it replaces them with their evaluated value.
DataSource
is a powerful component responsible for fetching data. The code above uses the /api/test
endpoint, which retrieves a string. This component has an identifier, message
, which allows accessing its exposed properties and methods.
The Text
element displays a message.value
expression. The engine recognizes that it must fetch data from the URL specified in the component identified with message
(it is the DataSource
). When the fetch has been completed, message.value
represents the returned string, and the UI refreshes to display that string.
Turn to the app running in the browser and refresh. Click the "Contact List" menu item; it will trigger fetching the test data (message) from the backend and display it on the screen:

In the following article, you will learn how the DataSource
component works together with others to fetch and leverage data from a backend.