Show an offline/server-unreachable banner so actions don't fail silently #133

Open
opened 2026-06-23 21:33:09 +00:00 by padreug · 0 comments
Owner

Problem

When the backend server is down or the device can't reach it (no network, server restart, NAT/relay hiccup), the webapp gives no up-front signal. A user can go all the way through a multi-step flow — e.g. composing and submitting a transaction in libra — only to have it error out at the final submit. From their side this looks like a bug or a broken feature, and the wasted effort is frustrating. They have no way to know the real cause is "the server isn't reachable right now."

Proposed solution

A global connectivity banner, shown across the webapp (and standalone apps), that surfaces when the app is offline or the server is unreachable. When the banner is visible, the user understands why an action might fail before they invest effort in it.

Behaviour to consider:

  • Detect both device offline (browser navigator.onLine / offline/online events) and server unreachable (API requests failing / health-check timing out even though the device has connectivity — the two are distinct and worth distinguishing in the message).
  • Persistent, unobtrusive banner (top of viewport) while the condition holds; auto-dismiss on recovery.
  • Clear copy explaining the app can't reach the server right now and changes may not save.
  • Ideally, gate or warn on submit actions while offline so a user isn't allowed to complete a flow that's guaranteed to fail (or at least preserve their input so it isn't lost on the failed submit).

Why it matters

Affects every module, but libra's transaction-entry flow is the motivating example: a long form that errors only at the end reads as a product bug rather than a transient connectivity issue. A shared banner fixes this once for all modules.

Scope

Cross-cutting — belongs in the shared app shell so all modules (and the standalone PWAs) inherit it, rather than being re-implemented per module.

## Problem When the backend server is down or the device can't reach it (no network, server restart, NAT/relay hiccup), the webapp gives no up-front signal. A user can go all the way through a multi-step flow — e.g. composing and submitting a transaction in **libra** — only to have it error out at the final submit. From their side this looks like a bug or a broken feature, and the wasted effort is frustrating. They have no way to know the real cause is "the server isn't reachable right now." ## Proposed solution A global connectivity banner, shown across the webapp (and standalone apps), that surfaces when the app is offline or the server is unreachable. When the banner is visible, the user understands *why* an action might fail before they invest effort in it. Behaviour to consider: - Detect both **device offline** (browser `navigator.onLine` / `offline`/`online` events) and **server unreachable** (API requests failing / health-check timing out even though the device has connectivity — the two are distinct and worth distinguishing in the message). - Persistent, unobtrusive banner (top of viewport) while the condition holds; auto-dismiss on recovery. - Clear copy explaining the app can't reach the server right now and changes may not save. - Ideally, gate or warn on submit actions while offline so a user isn't allowed to complete a flow that's guaranteed to fail (or at least preserve their input so it isn't lost on the failed submit). ## Why it matters Affects every module, but libra's transaction-entry flow is the motivating example: a long form that errors only at the end reads as a product bug rather than a transient connectivity issue. A shared banner fixes this once for all modules. ## Scope Cross-cutting — belongs in the shared app shell so all modules (and the standalone PWAs) inherit it, rather than being re-implemented per module.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
aiolabs/webapp#133
No description provided.