Welcome back! In the previous chapter, we built the Gateway, which acts as the invisible "hub" or "engine" of our system.
While the Gateway is powerful, it doesn't have a face. You can't "see" it unless you stare at text logs in a terminal. Now, we are going to build the dashboard for your engine.
Imagine you have a super-advanced car (the Gateway). It works perfectly, but it has no steering wheel, no speedometer, and no windows. It would be impossible to drive!
The Control UI is your dashboard. It is a website running on your computer that lets you:
The Central Use Case: You want to see a list of all devices currently connected to OpenClaw (like your iPhone or a Docker container) and check if they are "Online." Instead of typing commands, you just open a web page and look at the "Nodes" panel.
The Control UI is built inside the ui/ folder. It uses modern web technologies to be fast and responsive.
We use a library called Lit to build "Components." Think of these like LEGO bricks. We build a "Chat Brick," a "Settings Brick," and a "Node List Brick," and then snap them together to make the full website.
Vite is a tool that runs the website on your computer while you are developing. It is incredibly fast. If you change a line of code, the website updates instantly without reloading.
Just like the Gateway is the Server, the Control UI is a Client. It connects to the Gateway using the same phone line (ProtocolSchema) that your other nodes use.
Getting the dashboard up and running is straightforward.
First, we need to download the tools (Lit and Vite) required to build the interface.
# Go to the ui folder
cd ui
# Install the necessary libraries
npm install
Now we tell Vite to serve the website.
# Start the development server
npm run dev
What happens:
http://localhost:5173.How does a click on a web page travel to the Gateway? Let's look at the flow.
When you open the Control UI in your browser, it acts like a remote control.
The code for the UI is located in ui/src/. Let's look at how we build a simple component and connect it to the Gateway.
1. The Application Entry (main.ts):
This file sets up the WebSocket connection. It listens for messages from the Gateway and updates the rest of the app.
// ui/src/main.ts (Simplified)
// 1. Connect to the Gateway we built in Chapter 1
const socket = new WebSocket('ws://localhost:8080');
socket.addEventListener('open', () => {
console.log('Connected to OpenClaw Gateway!');
// The UI is now ready to send commands
});
2. A Visual Component (Lit): Here is how we create a simple "Status Badge" component that shows if we are Online or Offline. We use Lit to define how it looks (HTML) and how it behaves (JS).
// ui/src/components/StatusBadge.ts
import { html, LitElement } from 'lit';
import { customElement, property } from 'lit/decorators.js';
@customElement('status-badge')
export class StatusBadge extends LitElement {
// A variable to hold our status
@property() status = 'Offline';
render() {
// Return the HTML to display
return html`
<div class="badge">
System Status: <b>${this.status}</b>
</div>
`;
}
}
Explanation:
LitElement (the base brick).status. When this changes, the HTML updates automatically.render() function defines the HTML. ${this.status} injects the variable into the text.3. Sending a Command: When you click a button in the UI, we send a formatted message to the Gateway.
// Inside a component class...
sendMessage(text) {
const payload = {
type: 'CHAT_MESSAGE',
content: text,
// Configuration details might be added here
};
// Send JSON string to the Gateway
socket.send(JSON.stringify(payload));
}
This JSON message must match the rules defined in the ProtocolSchema, or the Gateway won't understand it.
In this chapter, we added a face to our project.
ui/ folder.Now that we have a Brain (Gateway) and a Dashboard (Control UI), we need something smart to say. In the next chapter, we will introduce the "AI" or logic engine that generates text.
Generated by Code IQ