I am not a big fan of email notifications because they can be ignored, and everyone assumes somebody else will look at an alert that lands in your inbox. So many times, critical issues get missed because of this diffusion of responsibility - alternatively, you get so many emails about alerts that you start complacently ignoring those emails.
Websites are consistent for every user, making them a more reasonable alerting and informational platform. They short-circuit the excuse "we didn't know about that" - if it's on the dashboard, everyone sees the same thing.
However, if you create lots of web dashboards like I have, you can end up with dozens of tabs open in your browser of choice (mine being Chrome), and it can get quite memory intensive and messy to navigate between tabs. Each dashboard fighting for attention in a sea of tiny tab titles.
Visuals of the Dashboard
This is the main dashboard with a clean and easy to follow interface
When you click on the hamburger icon you then see the menu as below:
Then when you click on a menu item the website appears full screen and the option selected is highlighted as below:
The Solution: A Unified Dashboard Navigator
It was suggested by my manager that I integrate all my dashboards into one website that has a hamburger-style icon in the upper left corner, then loads all the websites in an iframe. Keeping the hamburger icon small and the rest of the website available to display the whole website that's been selected from the hamburger menu means you get maximum visibility of the website, and one website can access all my dashboards that have been created over the years.
Excellent idea! So that is exactly what this blog post is about - creating that interface that combines all my dashboards into one website.
Building the Dashboard Navigator
The HTML Structure
The key to this solution is a simple HTML structure with three main components:
- A floating hamburger menu button
- A sliding sidebar with dashboard links
- A full-screen iframe for displaying the selected dashboard
<!-- Main Content - Full Screen -->
<div class="main-content">
<div class="iframe-container">
<iframe id="dashboardFrame"></iframe>
</div>
</div>
<!-- Floating hamburger icon -->
<div class="header">
<div class="menu-toggle" id="menuToggle">
<span></span>
<span></span>
<span></span>
</div>
</div>
<!-- Sliding sidebar -->
<div class="sidebar" id="sidebar">
<div class="dashboard-list" id="dashboardList">
<!-- Dashboard items generated here -->
</div>
</div>
Configuring Your Dashboards
The beauty of this system is how easy it is to add and manage dashboards. I simply maintain a JavaScript array with all my dashboard configurations:
const dashboards = [
{
name: "Mac Mini Caching Servers",
description: "View Mac Mini Metrics and Health",
icon: "🍎",
url: "https://dashboard.bear.local/mactransfer/"
},
{
name: "SSL Dashboard",
description: "Track SSL Dashboards and Expiry",
icon: "🔐",
url: "https://dashboard.bear.local/ssl/External/index.html"
},
{
name: "Exchange Queues",
description: "Monitor On-Prem Exchange Queues",
icon: "📫",
url: "https://dashboard.bear.local/exchangequeues/"
}
// Add more dashboards as needed
];
Styling for Maximum Screen Real Estate
The CSS ensures the hamburger icon floats over the content without taking up valuable screen space:
/* Floating hamburger, no banner */
.header {
position: fixed;
top: 20px;
left: 20px;
z-index: 1000;
}
/* Full screen iframe */
.main-content {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100vw;
height: 100vh;
}
Loading Dashboards Dynamically
The JavaScript handles loading the selected dashboard into the iframe:
function loadDashboard(index) {
// Remove active class from all items
document.querySelectorAll('.dashboard-item').forEach(item => {
item.classList.remove('active');
});
// Add active class to selected item
document.querySelector(`[data-index="${index}"]`).classList.add('active');
// Load dashboard in iframe
const dashboard = dashboards[index];
dashboardFrame.src = dashboard.url;
// Close sidebar on mobile
if (window.innerWidth <= 768) {
closeSidebar();
}
}
Customizing Icons
While emojis work great for icons, you might want something more specific. I found https://symbl.cc to be an excellent resource for finding appropriate symbols. Simply:
- Visit https://symbl.cc
- Search for relevant symbols (e.g., "server", "network", "security")
- Copy the symbol
- Replace the emoji in your dashboard configuration
For example, instead of using "🍎" for Mac Mini, you might find a more appropriate server symbol like "⌘" or "◙".
{
name: "Domain Controller Health",
icon: "◙", // Found a better symbol on symbl.cc
url: "https://dashboard.bear.local/adds/"
}
Important: Dealing with iFrame Security Headers
Since you're using an iframe, if you have security headers applied to your web server, you may need to set the correct values to display content in an iframe, else your connection will be blocked.
For IIS (Internet Information Services)
Add these headers to your web.config for the dashboard sites:
<system.webServer>
<httpProtocol>
<customHeaders>
<!-- Allow framing from your main dashboard domain -->
<add name="X-Frame-Options" value="ALLOW-FROM https://yourdashboard.domain" />
<!-- Or for same origin only -->
<add name="X-Frame-Options" value="SAMEORIGIN" />
<!-- For Content Security Policy -->
<add name="Content-Security-Policy"
value="frame-ancestors 'self' https://yourdashboard.domain;" />
</customHeaders>
</httpProtocol>
</system.webServer>
For Apache
Add to your .htaccess or Apache configuration:
# Allow from specific domain
Header always set X-Frame-Options "ALLOW-FROM https://yourdashboard.domain"
# Or for same origin
Header always set X-Frame-Options "SAMEORIGIN"
# Content Security Policy
Header always set Content-Security-Policy "frame-ancestors 'self' https://yourdashboard.domain;"
For Nginx
Add to your server block configuration:
# Allow from specific domain
add_header X-Frame-Options "ALLOW-FROM https://yourdashboard.domain" always;
# Or for same origin
add_header X-Frame-Options "SAMEORIGIN" always;
# Content Security Policy
add_header Content-Security-Policy "frame-ancestors 'self' https://yourdashboard.domain;" always;
Note: The ALLOW-FROM directive for X-Frame-Options is deprecated in modern browsers. I recommend using Content-Security-Policy with frame-ancestors for better browser support:
// Modern approach using CSP
Content-Security-Policy: frame-ancestors 'self' https://yourdashboard.domain;Conclusion
Creating this unified dashboard navigator has transformed how I monitor our infrastructure. No more tab chaos, no more missed alerts because they're buried in an inbox, and no more "I didn't see that" excuses. Everything is visible, accessible, and consistent for everyone on the team.
The best part? It took less than 200 lines of HTML, CSS, and JavaScript to solve a problem that was causing daily frustration. Sometimes the simplest solutions are the most effective.
If you're drowning in dashboard tabs like I was, give this approach a try. Your browser (and your sanity) will thank you!