The dashboard provides persistent UI that appears when users look up. Use it for status updates and notifications that don’t require full attention.
Basic Usage
session.dashboard.content.writeToMain('New message received');
With title and content:
session.dashboard.content.writeToMain('App Status\nConnected and running');
Dashboard Modes
Main Mode (Default)
session.dashboard.content.writeToMain('Status: Active');
Expanded Mode
More detailed information:
session.dashboard.content.writeToExpanded('Detailed status information here');
Clearing Dashboard
session.dashboard.content.writeToMain('');
Best Practices
Use for background info:
// ✅ Good - status updates
session.dashboard.content.writeToMain('3 unread messages');
// ❌ Avoid - main app content
session.dashboard.content.writeToMain('Welcome! Here is a long message...');
// ^ Use layouts for this instead
Keep updates brief:
// ✅ Good
session.dashboard.content.writeToMain('Recording: 1:23');
// ❌ Avoid
session.dashboard.content.writeToMain(
'You have been recording for 1 minute and 23 seconds'
);
Updates are auto-throttled:
MentraOS automatically throttles display updates to 1 every 300ms to prevent display desync:
// You can update frequently - cloud handles throttling
session.events.onTranscription((data) => {
if (data.isFinal) {
session.dashboard.content.writeToMain(`Message: ${data.text}`);
}
});
Common Patterns
Status Updates
session.events.onTranscription(async (data) => {
if (data.isFinal) {
// Show user input
session.layouts.showTextWall(data.text);
// Update dashboard with status
session.dashboard.content.writeToMain('Processing...');
// Process and show result
const response = await processInput(data.text);
session.layouts.showTextWall(response);
// Clear dashboard
session.dashboard.content.writeToMain('');
}
});
Real-Time Counters
let messageCount = 0;
session.events.onTranscription((data) => {
if (data.isFinal) {
messageCount++;
// Update main display
session.layouts.showTextWall(data.text);
// Show count in dashboard
session.dashboard.content.writeToMain(`Messages: ${messageCount}`);
}
});
Recording Status
let recordingStartTime: number;
let recordingInterval: NodeJS.Timeout;
function startRecording(session: AppSession) {
recordingStartTime = Date.now();
recordingInterval = setInterval(() => {
const elapsed = Math.floor((Date.now() - recordingStartTime) / 1000);
const minutes = Math.floor(elapsed / 60);
const seconds = elapsed % 60;
session.dashboard.content.writeToMain(
`Recording: ${minutes}:${seconds.toString().padStart(2, '0')}`
);
}, 1000);
}
function stopRecording(session: AppSession) {
clearInterval(recordingInterval);
session.dashboard.content.writeToMain('');
}
Notification Counts
let notificationCount = 0;
session.events.onPhoneNotification((data) => {
if (['Messages', 'Email'].includes(data.app)) {
notificationCount++;
session.dashboard.content.writeToMain(`${notificationCount} notifications`);
}
});
Dashboard API
| Method | Description |
|---|
content.writeToMain(text) | Update main dashboard |
content.writeToExpanded(text) | Update expanded dashboard |
content.write(text, modes) | Update specific modes |
content.onModeChange(callback) | Listen for mode changes |
Dashboard updates are automatically throttled to 1 per 300ms by MentraOS Cloud to prevent display desync.
When to Use Dashboard vs Layouts
| Use Case | Use Dashboard | Use Layouts |
|---|
| Main app content | ❌ | ✅ |
| Status updates | ✅ | ❌ |
| Notifications | ✅ | ❌ |
| User input/output | ❌ | ✅ |
| Persistent info | ✅ | ❌ |
| Detailed content | ❌ | ✅ |
Next Steps