Skip to content

How to Add a Page

Step-by-step template for adding a new page to the Control Center. No code to change beyond these 4 files.

<a class="sidebar-link" data-page="my-page" data-perm="page:my-page">
<span class="sidebar-icon">icon_name</span> My Page
</a>

Add inside a .sidebar-section. Use data-perm="page:my-page" to restrict access (managed via Access Management). Icon from Material Symbols.

<div class="page" id="page-my-page" data-perm="page:my-page">
<h1 class="page-title">My Page</h1>
<p class="page-desc">Short description</p>
<div class="section">
<div class="section-title">Data Section</div>
<div class="grid grid-4">
<div class="card">...</div>
<div class="card">...</div>
</div>
</div>
</div>
[data-page="my-page"] .sidebar-icon { background: #hexcolor; }
// If the page needs polling:
let myInterval = null;
async function loadMyData() { ... }
function startMyPolling() {
if (myInterval) clearInterval(myInterval);
loadMyData();
myInterval = setInterval(loadMyData, 30000);
}
function stopMyPolling() {
if (myInterval) { clearInterval(myInterval); myInterval = null; }
}
// Then in showPage() add:
// if (pageId === 'my-page') startMyPolling(); else stopMyPolling();

If the page uses client/site context, read currentClient and currentSite from the topbar context selector. These are set by MONITORING_CONFIG and stored in localStorage.

// Adding a new client:
MONITORING_CONFIG.clients.push({
id: 'new-client',
name: 'New Client Name',
sites: [{
id: 'site-1',
name: 'Site Name',
unifi: { siteId: '...' },
rpis: ['rpi001'],
zabbix: { hostGroupId: '...' },
zippin: { storeId: '...' }
}]
});

The topbar dropdown auto-populates from this config. No other code change needed.

AnimationDurationUsed on
fadeIn0.3sPage transitions (.page.active)
glassIn0.35sCards appearing (staggered by nth-child)
dotPulse2s infiniteBadge dots (live status indicators)
pulse1.5s infiniteGray badge dots (checking/loading)
msgIn0.2sAI chat messages appearing
typingDot1.2s infiniteAI typing indicator