2.3 KiB
Nav Consistency Pattern (Jul 12, 2026)
Principle
All portal pages must load nav from /nav.html — the single source of truth for nav links, hamburger toggle, and nav CSS. The only exception is index.html (dashboard), which keeps an inline nav that matches nav.html link-for-link.
Current state (post-Jul 12 fix)
| Page | Nav source | Status |
|---|---|---|
| index.html | Inline (matches nav.html) | OK — all 11 links + hamburger |
| services.html | Fetched | OK |
| servers.html | Fetched | OK |
| backups.html | Fetched | OK |
| audit.html, cost.html, cron.html, network.html, config.html, logs.html | Fetched | OK |
Conversion procedure (inline → fetched)
-
Replace the
<nav class="ops-nav">...</nav>block with<div id="nav"></div>. -
Move
initNav()into the fetch callback. The old pattern of callingwindow.initNav()before the nav HTML is injected is a race condition — it tries to wire up toggle listeners on elements that don't exist yet:// WRONG (initNav runs before nav HTML exists): window.initNav(); // ... later ... fetch('/nav.html')... // RIGHT (initNav runs AFTER nav HTML is injected): fetch('/nav.html').then(function(r) { return r.text(); }).then(function(h) { document.getElementById('nav').innerHTML = h; if (typeof window.initNav === 'function') window.initNav(); }).catch(function(e) { console.warn('Nav failed:', e); }); -
Keep
window.initNav()— never useOps.initNav()or bareinitNav()inside a strict-IIFE. The nav init function is exported onwindowinapp.js/utils.js.
Index.html: inline nav maintenance
The dashboard keeps inline nav. When /nav.html gains or loses links, update index.html's inline nav to match. Key elements:
class="nav-logo-text"on the brand span- Hamburger toggle:
<button class="nav-toggle" id="navToggle" ...> - All 11 links with
data-pathattributes class="nav-link"andtarget="_blank"on Grafana
Verification checklist
<div id="nav">placeholder present (fetched pages only)initNav()called AFTER.innerHTML = hin fetch callback- No orphan
window.initNav()outside fetch block - index.html has all current nav.html links + hamburger toggle
- HTTP 200 on all pages
/nav.htmlserves directly (not just through FastAPI proxy)