Osy#the first language built for agents
Agents firstAgentic appsWorkflowsDurable Execution — built inSecurityTestingThe editorThe UI modelOne program

Reference / UI

Connection

Connection.State · Connection.Attempts · Connection.Retry() · Connection.Reload()

The live state of the browser's link to the server, and the two verbs that recover it. A component you nominate as your app's connection-loss surface reads `Connection.State` to switch between "reconnecting" and "lost", shows `Connection.Attempts`, and calls `Connection.Retry()` / `Connection.Reload()` from its buttons. The platform detects the drop and mounts your surface; it renders none of the chrome.

stable1 example compiled by CIuiconnectionofflineresilience

Summary#

Connection is the live state of the browser's link to the server. When the server drops mid-session — it restarted, the network went away, a deploy is rolling — the platform detects it, keeps the current page intact, and mounts the component you nominated as your connection-loss surface (see UI surfaces (app.Ui)). That surface reads Connection to tell the user what happened and offer a way back.

It exists so you can write that surface — a full-screen "can't reach the server" curtain, a quiet "reconnecting…" strip, a branded card — in your own design. The platform ships a plain default overlay if you nominate none; the moment you do, Connection is what your surface binds to.

Connection is available only inside your nominated connection-loss surface. An ordinary page never reads it (there is nothing for it to say there) — reading it elsewhere is an unbound-name error.

Signature#

Connection.State       // where the link stands right now — a ConnState (Ok / Reconnecting / Lost)
Connection.Attempts    // how many reconnect attempts have been made since the drop (an int)

Connection.Retry()     // try the server now — clears the surface if it answers
Connection.Reload()    // reload the page

Connection.State is a ConnState — a three-member enum:

MemberMeaning
ConnState.OkThe server is reachable. Your surface is unmounted, so you never render this case.
ConnState.ReconnectingThe link just dropped; the platform is retrying with backoff. A soft, transient state.
ConnState.LostSeveral retries failed — the server looks genuinely gone. Offer Retry / Reload.

Description#

How a drop is detected#

Every request the page makes reports up or down. A request that can't reach the server at all, or that comes back as a gateway error (the server is down or restarting), flips Connection.State to Reconnecting. The platform then pings the server on a backoff, escalating to Lost after a few failed tries, and returns to Ok the instant anything succeeds. A normal error response — a 401, a 404, a 500 — is not a connection loss: the server answered, so the link is fine, and your ordinary error handling still runs.

Does my surface re-render as the state moves?#

Reading Connection in your surface's render subscribes it: when the state moves Reconnecting → Lost → Ok, or the attempt count climbs, the surface re-renders. A switch on Connection.State re-runs on every transition with no polling.

Your surface must render with the server gone#

Your connection-loss surface has to render with the server gone, so the platform fetches it up front — while the link is still alive — and holds it ready. That puts one real constraint on the component: it must be self-contained. Build it from the component built-in elements only — no child components to fetch, no data to load — because anything it would fetch when it mounts is exactly what's unreachable. It renders from Connection and nothing else.

Retrying by hand — Connection.Retry()#

Connection.Retry() pings the server immediately — the button a user presses when they think the network is back. If the server answers, the surface clears itself; if not, the state stays Lost and the backoff continues. Connection.Reload() reloads the page outright — the heavier reset for when a retry isn't enough.

Neither is required: a surface can simply say "reconnecting…" and let the automatic backoff recover on its own. The verbs are there for the Lost case, where the user wants a button.

Can I name something Connection? — shadowing#

Connection is an ambient name, not a keyword. A parameter or state member named Connection shadows it, exactly as a local variable shadows any other ambient. Nothing is reserved.

Examples#

A connection-loss surface#

One component covers both states — a quiet strip while reconnecting, a blocking card once lost. Nominate it with UI surfaces (app.Ui) (app.Ui = new AppUi { ConnectionSurface = OfflineOverlay };).

// The tokens this overlay draws with. They are YOUR app's — the platform declares none of them — so a copy of this
// example needs a theme that names them (or your own names substituted throughout).
theme App {
  Colors {
    Surface0 = "#FFFFFF"; Surface1 = "#F7F8FA";
    Border = "#E3E6EA"; BorderStrong = "#C7CCD3";
    FillAccent = "#0077B6"; OnAccent = "#FFFFFF"; TextMuted = "#6B7280";
  }
  Radius { Card = "12px"; Control = "8px"; }
  FontWeight { Medium = 500; }
}

[AllowAnonymous]
component OfflineOverlay() {
  action Retry()  { Connection.Retry(); }
  action Reload() { Connection.Reload(); }

  render {
    if (Connection.State == ConnState.Lost) {
      // A full-screen curtain: the server looks gone, so block the dead view and offer a way back.
      Row(align: Align.Center, justify: Justify.Center, position: Position.Fixed, inset: 0, bg: Colors.Surface0) {
        Box(bg: Colors.Surface1, border: Colors.Border, borderW: 1, rounded: Radius.Card, p: 5, maxW: "400px") {
          Stack(gap: 3, align: Align.Center) {
            Text("Can't reach the server", fontWeight: FontWeight.Medium);
            Text("Your connection dropped. Retry, or reload the page.", color: Colors.TextMuted, textAlign: TextAlign.Center);
            Row(gap: 2, w: "100%") {
              Pressable(onClick: Retry,  grow: 1) { Row(align: Align.Center, justify: Justify.Center, h: "40px", bg: Colors.FillAccent, color: Colors.OnAccent, rounded: Radius.Control) { Text("Retry"); } }
              Pressable(onClick: Reload, grow: 1) { Row(align: Align.Center, justify: Justify.Center, h: "40px", borderW: 1, border: Colors.BorderStrong, rounded: Radius.Control) { Text("Reload"); } }
            }
          }
        }
      }
    } else if (Connection.State == ConnState.Reconnecting) {
      // A quiet, non-blocking top strip — a transient blip should not lock the UI.
      Row(align: Align.Center, justify: Justify.Center, position: Position.Fixed, top: 0, left: 0, right: 0, py: 2, bg: Colors.Surface1, borderBW: 1, border: Colors.Border) {
        Text("Reconnecting…", fontWeight: FontWeight.Medium);
      }
    }
  }
}

Showing the attempt count#

Text("Reconnecting… (attempt " + Connection.Attempts + ")");

See also#

  • UI surfaces (app.Ui)app.Ui, where you nominate the component Connection binds to.
  • component — components, render blocks, actions, and the built-in elements a surface is built from.
  • routes and pages — how a failed navigation rolls back and leaves the current page intact underneath the surface.

Related

UI surfaces (app.Ui)

`app.Ui` nominates the app's own components for the "system surfaces" the platform would otherwise render a bare…

component

The one archetype for all UI: a bounded reactive unit — typed props, reactive members (fields, `live`…

routes and pages

How a component becomes a page: it declares a route with `[Page("/catalog/{slug}")]`, and navigating to a matching path…