Source Code

<footer class="site-footer">
  <div class="footer-top">
    <div class="footer-col">
      <p class="footer-brand">Nimbus</p>
      <p class="footer-tag">Infrastructure for modern teams.</p>
    </div>
    <div class="footer-col">
      <p class="footer-heading">Product</p>
      <a href="#">Features</a>
      <a href="#">Pricing</a>
      <a href="#">Changelog</a>
    </div>
    <div class="footer-col">
      <p class="footer-heading">Company</p>
      <a href="#">About</a>
      <a href="#">Careers</a>
      <a href="#">Blog</a>
    </div>
  </div>

  <div class="footer-bottom">
    <span class="footer-copy">© 2026 Nimbus, Inc.</span>
    <a class="status-link" id="statusLink" href="#" role="status">
      <span class="status-dot" id="statusDot"></span>
      <span id="statusText">Checking status…</span>
    </a>
  </div>
</footer>

Footer Live System-Status Indicator — Real Polling, Honest Unknown State

Footer Live System-Status Indicator · Footers · Plain HTML, CSS & JS · Live preview

What's included

Features

Genuine periodic polling keeps the indicator current for as long as the page stays open, not just a one-time check on load
Single shared STATUS_CONFIG lookup drives both the dot's color/animation and its text label, preventing any possible mismatch
Distinct, honest "unknown" state shown if a status check itself fails, rather than silently displaying stale or falsely reassuring data
aria-label updates in sync with the visible text on every status change, keeping the accessible name current for screen reader users
Pulsing animation reserved specifically for degraded/outage states, keeping the operational state calm and unobtrusive
Status link doubles as a real navigational element pointing to a full status page, not just a decorative indicator
Structured so only fetchStatus() needs replacing to connect to a real status API in production

About this UI Snippet

Footer Status Indicator — Small Widget, Several Correctness Details

Screenshot of the Footer Live System-Status Indicator snippet rendered live

A small colored dot in a footer linking to "status.example.com" is a common pattern — but making it genuinely trustworthy (rather than a static green dot that never actually reflects reality) requires a few specific correctness details: real periodic polling, one shared mapping from status to every visual signal, an honestly distinct "unknown" state, and an accessible label that updates along with the visible text.

One lookup table, not scattered conditionals

STATUS_CONFIG maps every possible status key (operational, degraded, outage, and unknown) to both a CSS class (controlling the dot's color and pulse animation) and its display text, together as one unit. applyStatus() is the single function anything in the codebase would call to update the indicator — whether triggered by an initial page-load check, a periodic poll, or (in a more advanced version) a real-time webhook push. Because every possible caller funnels through this one function and one lookup table, the dot's color and its text label can never independently drift out of sync with each other.

An honest "unknown" state, distinct from "operational"

If the status check itself fails (a network error, a malformed response), the code explicitly calls applyStatus('unknown') rather than either leaving the previous status displayed unchanged or defaulting to a falsely reassuring "operational" appearance. A failed health check is itself meaningful information — silently showing stale or incorrect status data would be worse than plainly admitting the current status couldn't be determined.

`aria-label` updates alongside the visible text, not just once

applyStatus() doesn't only update statusText.textContent — it also rewrites the link's aria-label to include the current status wording. This matters specifically because the link's *accessible name* (what a screen reader announces) is derived from its aria-label when one is present, which takes priority over its visible text content. Without updating both together, a screen reader user could hear a stale, outdated status label indefinitely, even as the visually rendered text correctly updates on screen.

Periodic polling, not a one-time check

refreshStatus() runs once immediately on load and then again on a recurring interval via setInterval — a status indicator that only checks once when the page first loads would silently go stale the moment a user leaves the tab open, showing "all systems operational" for a page that's been open for hours regardless of what's actually happened to the service since. Polling periodically (at whatever interval makes sense for the real deployment) keeps the indicator meaningfully current for as long as the page stays open.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Ask an AI assistant to explain why a failed status check should be shown as a distinct "unknown" state rather than either the last-known status or a default healthy appearance, and to discuss the accessibility distinction between an element's visible text content and its aria-label-derived accessible name. It's also worth asking for a version that also shows a small "last checked X seconds ago" timestamp, or one that uses the Page Visibility API to pause polling while the tab is in the background and resume (with an immediate re-check) when it becomes visible again.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a footer with a live system-status indicator in HTML, CSS, and vanilla JavaScript — no external library.

Requirements:
- A realistic multi-column site footer with a status indicator link at the bottom, showing a small colored dot and a text label describing current system health (e.g. operational, degraded performance, or outage), simulating a real status API poll with a delayed Promise.
- Define a single shared configuration object mapping each possible status value to both its dot styling (color/animation class) and its exact display text — every place in the code that updates the displayed status must go through one shared function using this same configuration, so the dot's color and its text can never disagree with each other.
- If the simulated status check itself fails (reject its promise), show a visually and textually distinct "status unavailable"/unknown state — do not leave a previous status displayed unchanged, and do not default to a falsely reassuring "operational" appearance.
- Update the status link's aria-label (not just its visible text content) every time the status changes, so its accessible name stays in sync for screen reader users — explain in a comment why aria-label needs to be updated separately from the visible text.
- Poll for status periodically after the initial page-load check (using setInterval), so the indicator can reflect a status change without requiring a full page reload.
- Give a pulsing animation specifically to the degraded/outage dot states, while keeping the operational state visually calm and static.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Observe the initial status checkThe dot starts in a neutral "checking" state and resolves to a real status (mostly "operational" in this simulated demo) shortly after load.
  2. 2
    Wait for the periodic re-checkEvery 15 seconds in this demo (tune for production), the indicator polls again and updates if the status has changed.
  3. 3
    Notice the pulsing animation on degraded/outage statesA subtle pulse on the dot draws more attention specifically when something is actually wrong, staying calm and static during normal operation.
  4. 4
    Tab to the status link with a keyboardIts aria-label announces the current status text directly, kept in sync with the visible label on every update.
  5. 5
    Replace fetchStatus() with a real API callPoint it at your actual status provider's API or your own health-check endpoint, keeping the same resolve-with-a-status-key contract.

Real-world uses

Common Use Cases

SAAS
SaaS product footers
The canonical use case — a small, trustworthy live status indicator in the footer of any web application or marketing site.
DEVTOOLS
Developer platform and API status
Developer-facing platforms benefit from a persistent, always-visible indicator of API/service health across every page.
ADMIN
Internal admin tool footers
Internal tools depending on other internal services benefit from surfacing that dependency's health status directly in the UI.
ECOMMERCE
E-commerce checkout reliability signal
A visible, honest status indicator can reassure users during checkout or high-stakes flows, as long as it genuinely reflects reality.
Related: Command Bar Footer
See the Command Bar Footer for a related footers pattern worth pairing with this one.
Related: Scroll Progress Footer
See the Scroll Progress Footer for a related footers pattern worth pairing with this one.
Related: Split Newsletter & Social Footer
See the Split Newsletter & Social Footer for a related footers pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

applyStatus("unknown") is explicitly called, showing a distinct neutral state rather than leaving the previous status displayed (which could be stale and wrong) or defaulting to a falsely reassuring "operational" appearance. A failed check and an actual outage are treated as two different, honestly distinguished situations.

Driving both the dot's CSS class and its text label from the exact same lookup, inside one shared applyStatus() function, guarantees they can never disagree with each other — there's no code path where the color could update without the text, or vice versa.

When a link has an aria-label, that label — not its visible text content — determines what a screen reader announces as the link's accessible name. If only the visible text were updated, a screen reader user could hear a stale, outdated status indefinitely, even as everyone else sees the correct, updated text on screen.

No — refreshStatus() is called once immediately and then again on a recurring interval via setInterval, so the indicator stays reasonably current for as long as the page remains open, rather than silently going stale after the first check.

Reserving the pulsing animation for states that need attention keeps the normal, healthy state visually calm and unobtrusive — a constantly pulsing dot even during normal operation would either be needlessly distracting or would dilute the animation's usefulness as an attention signal when something is actually wrong.

Replace the body of fetchStatus() with a real fetch call to your status provider's public API (many, like Statuspage.io, offer a simple summary endpoint) or your own health-check endpoint, keeping the same Promise-resolving-to-a-status-key contract so the rest of the code works unchanged.