Skip to content

Connection Status

“How did you get in?”

“Page four of your own manual,” Trace said.

Meridian Lattice, the Monday after

A page that loses its connection looks completely normal, but is frozen. If the user fills in a form over a dead connection, everything is gone when she presses send.

// main.ts, runs once when the app starts
import { defineLtConnectionStatus } from "@lo-tek/interfaces/connection-status"
import "@lo-tek/interfaces/tokens.css"
import "@lo-tek/interfaces/connection-status.css"
defineLtConnectionStatus()

The server by definition cannot tell you that it is unavailable. If it is down, nothing comes from it to render. So the component creates the content itself, and the builder function sets data-ignore-morph so that a later patch does not tear the bar away the moment the connection is back. See Markup and behaviour.

The browser only knows whether the machine has a network, not whether the server answers. An office network with no route to the internet, a server that is down, or a stream that has dropped all count as “online”.

So the app reports it itself:

const connection = document.querySelector("lt-connection-status")
if (!connection) throw new Error("element not found")
let response
try {
response = await fetch("/api/routes", { method: "POST", body })
} catch {}
if (response && ![502, 503, 504].includes(response.status)) connection.reportSuccess()
else connection.reportFailure()
MethodWhen you call it
reportFailure()A request got no answer, or a gateway answered 502, 503 or 504 because the server behind it is gone
reportSuccess()The server answered, an error status included: a 400 or a 500 comes from a server that is there

reportFailure(element) and reportSuccess(element) from @lo-tek/interfaces/connection-status do the same, but first wait until the element is registered.

The component also listens to the browser’s offline and online, so a network that disappears is caught without you doing anything.

AttributeDefault
offline-text“No connection. What you type is not being saved.”
online-text“Connection restored.”
EventWhen
connection-lostThe bar appears. Once per outage, however many offline events the browser sends
connection-restoredThe connection is back
ClassWhat it is
.lt-connection-statusThe host element. It is display: contents and takes up no space
.lt-connection-status__barThe bar itself. Has data-state="offline" or data-state="online"
VariableFallback
--lt-connection-status-layer1000
--lt-connection-status-paddingvar(--lt-spacing-2) var(--lt-spacing-4)
.lt-connection-status__bar {
--lt-connection-status-layer: 9999;
}

What a screen reader is given when the recipe above is used, step by step. It is checked through AT-SPI, the interface Orca reads, in Chromium and Firefox, on every change, by check-accessibility-tree.ts, and every change the check lists as a mutation must make it fail.

  1. Call document.querySelector("lt-connection-status").reportFailure(): "No connection. What you type is not being saved." announced once, polite.
  2. Call document.querySelector("lt-connection-status").reportSuccess(): "Connection restored." announced once, polite.

The component itself is role="status" with aria-live="polite", not alert, from the moment it is connected, so the region exists before the bar and its text arrive; a role or politeness you write stays. The message is important, but should not interrupt in the middle of a word. It stays until the connection is back, so someone who reads slowly has time to read it.

While a modal dialog is open, the bar is inert and sits under the backdrop, like everything else outside the dialog. If the connection drops then, the user learns about it only when the dialog closes.

Colour alone does not carry the message: the text says what is wrong. In Windows high contrast mode, custom colours and backgrounds are removed, so the bar gets a border in CanvasText; otherwise it would be invisible.