142

Monitoring Dashboard Website Template

£29 View live demo or the whole Vault, £79.20

A seven-page uptime monitoring and status dashboard set in one monospace face on boxed black-ruled grids, under a yellow band that always says what is broken. Ninety days of every service read as one grid of squares, plus incidents with a live timeline, monitors, an on-call rota, a public status page and settings.

FlipDraggable advanced
13 more details
data-vizkeyboard-navigationcount-upfilterflip-layoutdraggabletheme-switchstaggerdialog-animationfocus-managementhover-effectprogressive-enhancement 2 colour palettes
Colour

Released

About this template

A working monitoring dashboard for anything that has to stay up: a SaaS status and uptime console, a DevOps or SRE dashboard, a hosting company's network status, an IoT or fleet health board, or an IT service desk. The worked example is Signal Box, the console the platform team at Brockhall Tickets, a venue ticketing company in Leeds, uses to watch twelve services across two regions.

Read the full template overview

The look is set in one monospace face on an off-white sheet. Data sits in boxed grids with full-strength black rules and square corners, and a yellow band across the top of every page says what is broken right now and links to it. Health is never painted: a good day is a grey square, so the only colour on a page is the trouble. Light and dark themes share the same token names. For buyers who find it too loud, a second skin, Calm, ships in the same stylesheet: a proportional sans, soft grey hairlines, rounded panels and green, amber and red states, switched by one attribute on the page.

Every page has something to handle. The overview reads ninety days of every service from one grid of squares by pointer or arrow keys. Incidents filter, open into a timeline and take the next update. Monitors chart each check minute by minute with a crosshair, pause, sort and add new ones. On call hands shifts to someone else and reorders the escalation by dragging. The status page previews what customers see in each state, and settings replays an alert rule against the last day as you move its threshold.

Monitoring Dashboard - website template preview

What's included

11 items
  • Seven pages: Overview, Incidents, Monitors, On call, Status page, Settings and a UI elements page, on one stylesheet and one script
  • A yellow live band on every page that names the open incident, rewritten when you post an update or resolve it
  • Uptime grid of twelve services by ninety days with a readout cell, arrow-key reading, and a 30, 60 or 90 day switch that sweeps the squares back in
  • Incident list with status, severity and search filters, a timeline with a four-step progress bar, an update composer and a declare-incident dialog
  • Monitors table with three regions, sort, pause and resume, a minute-by-minute response chart with a crosshair and region switch, and a new-monitor drawer with validation
  • On-call rota with per-day overrides from a popover, and an escalation policy reordered by drag, buttons or arrow keys, with a timeline of who gets paged when
  • Public status page preview in operational, degraded and outage states, with grouped 90-day strips, past days and an email subscribe form
  • Settings with an alert rule replayed on 24 hours of data, notification switches, team invites, API key reveal, copy and rotate, and a typed delete confirmation
  • Two skins in one stylesheet: Signal, the loud monospace default, and Calm, a conventional SaaS look in Red Hat Text with rounded panels and traffic-light states, each in light and dark
  • Light and dark themes on the same tokens, self-hosted fonts and a designed phone menu
  • Every control works without GSAP; reduced motion and no JavaScript leave complete pages

Perfect for

5 use cases
  • Uptime monitoring and status pages for SaaS products
  • DevOps, SRE and platform team dashboards
  • Hosting, network and API status consoles
  • IoT, fleet and device health boards
  • IT service desk and incident management tools

How it works

5 sections

Static pages first

Every page is plain HTML with its figures written into the markup, so it reads the same without JavaScript. The uptime grid is a real table whose cells carry their state, uptime and cause as data attributes. Incidents, monitor series and the alert rule's day of readings sit in small JSON blocks on their pages, which the script reads when you interact.

The uptime grid

One square a day for each service. The script gives the grid a single tab stop that moves with the arrow keys, Home and End, and fills the readout above it from whichever square is under the pointer or focus. The range switch hides older columns and sweeps the remaining squares up column by column, oldest first.

Incidents and the band

Posting an update adds it to the top of the timeline, moves the progress bar, changes the row's status and rewrites the yellow band. Resolving the last open incident turns the band into an all-clear with a link to the status page. Declaring an incident adds a row, selects it and pages on call in the band.

Charts and the alert replay

Response charts are SVG paths scaled to a fixed view box, with a crosshair, a dot and a label placed on whole pixels. Switching region tweens the line between series. In settings, the threshold slider and duration list re-run the rule over 288 five-minute readings and shade each run that would have paged someone.

Overlays, reordering and fallbacks

Dialogs and the drawer are native dialog elements, so focus stays inside and Escape closes them. The escalation list reorders by dragging its handle, by buttons or by arrow keys on the handle, with Flip smoothing the move. If GSAP fails to load, every control still works; only the motion is missing.

Plugins Flip, Draggable
Difficulty Advanced
Colour palettes 2 ready-made palettes, each measured for AA contrast. Switch with one attribute, or copy the values you want into :root. Try them in the preview above.
Includes HTML + JS + CSS source, documentation, AI setup prompt, lifetime updates

Lighthouse, as measured

Google Lighthouse on this template's demo (7 pages, lowest score shown), from the latest scan. A measurement of the demo as shipped, not a promise for your page.

Accessibility
100
Best practices
100

No performance score, on purpose. That figure depends on how you deploy: your server's compression and caching, your CDN, the connection and the device doing the test, none of which the code controls. The same page can score very differently on two consecutive runs, so measure it where it will live.

Questions about this template

Can this be a status page or dashboard for something other than ticketing?

Yes. Brockhall Tickets is only the worked example. Rename the twelve services in the uptime grid, the monitors and the status page groups, and it becomes the uptime console for a SaaS product, a hosting company's network status, a DevOps or SRE dashboard, an IoT fleet board or a council IT service desk. The band, grid and timelines do not depend on the subject.

How do I connect it to my real monitoring data?

The pages are static, so fetch your data and write it into the same markup. Each uptime square takes data-s for its state, data-u for its uptime and data-n for its cause; incidents, monitor series and alert readings are JSON blocks on their pages. Point those at Better Stack, Checkly, Prometheus, Uptime Kuma or your own API and the script keeps working.

Do the incident updates, overrides and new monitors save anywhere?

No. They change the page you are on so you can see the whole flow, but nothing is stored and a reload starts again. Posting an update, declaring an incident, adding a monitor, saving an override, inviting a teammate and rotating the API key are all front end only. Send each form's values to your backend or incident tool to make them real.

Does the status page subscribe form send emails?

Not on its own. It checks the email address and the chosen groups, then shows a confirmation message. It collects an email address and which service groups to hear about. Post those to Buttondown, Mailchimp, Formspree, Netlify Forms or your own status mailer, and send the confirmation email from there.

How do I change which states get a colour?

Healthy squares use --ok-cell, degraded use --warn and down use --down, all in the token blocks at the top of assets/style.css. Keep healthy quiet if you want trouble to stand out. If you add a maintenance state, give it a new data-s value and one CSS rule in the uptime grid and status strip sections.

Is there a quieter version if the black rules and yellow band are too much?

Yes. The Calm skin ships in the same stylesheet: Red Hat Text instead of the monospace, soft grey hairlines, rounded panels, a tinted incident strip and green, amber and red states. Add data-palette="calm" to the html element on each page. To ship only one skin, the README lists which token blocks, rules and font file to delete.

Can I add more services or show a different number of days?

Yes. Copy a row of the uptime grid and change its name and squares; the readout and keyboard reading pick it up. The grid assumes the newest day is the last square. To show 14 or 180 days, change the number of squares per row, the colspan on the day header and the buttons in the range switch.

Paid template

Purchase to unlock the code.

Buying Monitoring Dashboard opens the HTML, CSS and JavaScript source, the full documentation, an AI setup prompt for your editor, and every update we ship to it. Standard license: unlimited personal and commercial projects. Every paid product is tested for desktop and mobile layouts, reduced-motion handling, animation cleanup and keyboard controls wherever there is something to operate.

£29 Standard license, unlimited projects

Browse free effects

Or the whole library: the Vault, £79.20, one payment.

Documentation

Quick Start

  1. Unzip the folder and serve it:

Code snippet omitted: it ships with the download.

  1. Open /index.html (or the folder with a trailing slash) so the relative assets/ paths resolve.
  2. Change the app name in .brand and the workspace name (Brockhall Tickets) in the page heads and footers.
  3. Replace the services, incidents and monitors with your own (see "Re-pointing the data").

No build step. Each page is a plain HTML file with assets/style.css, GSAP from a CDN and assets/script.js (or script.min.js).

Two skins

Both skins live in assets/style.css and work in light and dark on the same token names. Signal is the default; Calm is switched on by one attribute on the root element:

Skin Attribute Character Faces
Signal no attribute Boxed grids on full black rules, square corners, a yellow live band, orange buttons, grey healthy days Red Hat Mono 400 and 600, Martian Mono 500 for readouts
Calm data-palette="calm" Soft grey hairlines, 6 and 8px corners, light shadows, a tinted band with an icon, blue buttons, green healthy days Red Hat Text 400 to 600 for words and figures, Red Hat Mono for ids, keys and URLs

Code snippet omitted: it ships with the download.

Put it on the <html> of every page. The picker on the GSAP Vault preview is demo-only and is not in the download.

To ship one skin and delete the other:

  • Keep Signal: delete the two :root[data-palette="calm"] token blocks, the CALM SKIN section at the end of style.css, the Red Hat Text @font-face and assets/fonts/red-hat-text-latin.woff2.
  • Keep Calm: copy the values of :root[data-palette="calm"] into :root and of :root[data-palette="calm"][data-theme="dark"] into :root[data-theme="dark"], delete those two blocks, and remove the :root[data-palette="calm"] prefix from the rules in the CALM SKIN section. Then delete the Martian Mono @font-face, its file and its <link rel="preload"> in each page head. Or simply keep the attribute and leave Signal in place: the browser never downloads a face the page does not use.

Using It With Your Own Design

  • Colour: the tokens at the top of assets/style.css. :root is light; :root[data-theme="dark"] restates the same names. The first comment lists the measured contrast pairs; the Calm blocks carry their own. Solid buttons keep dark text on the orange accent because white on it falls below 4.5:1.
  • The band: --band (yellow) and --on-signal (its text). It is the loudest thing on the page by design; keep it to one colour.
  • States: healthy --ok-cell, degraded --warn, down --down (the accent itself in Signal, red in Calm). Degraded squares carry an inset ink edge so the light yellow still reads as an indicator.
  • Type: Red Hat Mono for all text and Martian Mono for the large readouts, self-hosted in assets/fonts/. Calm sets Red Hat Text for both and keeps the mono in --font-code for ids, keys and URLs. Swap --font, --font-read and --font-code and the @font-face rules.
  • Shape: --radius, --radius-s, --cell-radius, --dot-radius and the --shadow-* tokens. In Signal they are all zero or a hard offset shadow in ink; Calm rounds and lifts with the same tokens.

Pages and Configuration

Shared shell

Every page has the band ([data-band]), the top bar (.bar) with the page links split by pipes, the theme toggle ([data-theme-toggle]), a Declare incident button, the phone menu ([data-menu-btn] and #phone-menu) and a footer page list that is also the no-JavaScript route between pages. To add a page, copy one, change its <title>, heading and content, and add its link to .nav, #phone-menu and .foot-pages on every page. Mark the current link with aria-current="page".

The theme follows the visitor's system setting until they press the toggle; the choice is kept in localStorage under signalbox-theme.

The band

Write the current state into [data-band-text] and point [data-band-link] at it. On the incidents page the script rewrites the band whenever an update changes an incident, and shows an all-clear when nothing is open. Delete the band markup if you do not want it; nothing else depends on it.

Uptime grid (index.html)

table[data-matrix] has one row per service. Each day is <td><i></i></td>, oldest first and today last. A healthy day needs no attributes. Any other day takes:

  • data-s: deg or down
  • data-u: that day's uptime, for example 99.31
  • data-n: the cause, either an incident id such as INC-2207 (becomes a link) or a short note

The last cell of each row is the uptime column; give it data-up30, data-up60 and data-up90 so the range switch can show the right figure. The range buttons ([data-range-switch]) hide older columns; phones start on 30 days.

Incidents (incidents.html)

The table rows are the no-JavaScript list. The script reads #incident-data, a JSON array of incidents with id, title, sev (1 to 3), status (Investigating, Identified, Monitoring or Resolved), started, dur, services, lead and updates (newest first, each with t, status, by and text). Keep the table and the JSON in step. incidents.html#INC-2203 opens that incident; incidents.html#declare opens the declare dialog, which is where every page's Declare incident button goes.

Monitors (monitors.html)

Each row has data-mon, data-name, data-s (ok, deg or paused) and data-up. #monitor-data holds end (the time of the last point), regions, and per monitor limit (the alert line in ms, or null) and series (one array of 60 readings per region, or null for a heartbeat check, which shows an empty state instead of a chart).

On call (on-call.html)

Each shift is a button[data-shift] with data-layer, data-day and data-who (a key from the popover's radio list). Add data-override to show the corner mark. The escalation list is ol[data-esc]; each step's select[data-wait] sets its wait in minutes, and a wait of 0 marks the last step. The block bar and sentence under "If nobody answers" are worked out from the list order and waits.

Status page (status.html)

Groups are .grp blocks with a button[data-grp] that controls the next .grp-body. Each component is .comp[data-comp] with a 90-square .strip; phones show the last 30. The preview switch ([data-preview]) and its three messages live in initStatusPage in script.js; on your real public page, drop the preview bar and write the current state into .pub-state with data-state="ok", deg or down.

Settings (settings.html)

#rule-data holds 288 five-minute readings. The threshold slider ([data-th]) and duration list ([data-th-for], in readings) shade each run that would have paged someone and update the count. Switches are button[role="switch"][data-switch]. The delete button unlocks when [data-del-input] matches the workspace slug, which you set in the label and in initSettings.

UI elements (components.html)

Every part used on the other pages, in its states. The rail filter matches section names and contents. Delete this page from a finished site or keep it as your reference.

Accessibility

  • Native buttons, links, inputs and dialogs throughout, with a visible focus ring for keyboard use only.
  • The uptime grid is a grid with one tab stop; arrow keys, Home and End move by day and service, and the readout announces each square. The response chart is a focusable group read with the arrow keys.
  • Dialogs and the drawer are native dialog elements: focus stays inside, Escape closes them and focus returns to the button that opened them. The phone menu and override popover close on Escape and outside clicks and hand focus back.
  • State is never colour alone: every square, badge and strip has a word beside it or in the readout.
  • Reduced motion turns off the sweep, count-ups, the band pulse and the reorder animations; everything stays usable. Without JavaScript every page shows its full content, and controls that need scripting are hidden.

Dependencies

  • GSAP 3.12+ (demo built against 3.15.0) from jsDelivr. Flip is loaded on monitors.html and on-call.html, Draggable on on-call.html. All optional: without them sorting and reordering still work, without the motion, and the escalation handle answers to arrow keys.
  • Red Hat Mono, Martian Mono and (Calm only) Red Hat Text, self-hosted in assets/fonts/ (latin, the weights used). SIL Open Font License; see the OFL-*.txt files beside them.
  • No other libraries. Page loads crossfade with a CSS view transition where the browser supports it.

Teardown

Each page is standalone and needs no teardown on an ordinary page load. If you mount a page inside an app that swaps views without reloading, call window.SignalBox.destroy() when the view unmounts: it removes the document and window listeners, observers and drag handlers the script added and stops its tweens.

Worked examples, the events and programmatic API, and the class reference ship with the download, alongside the full source.