Skip to content

State Bar JavaScript API

Your own State Bar items are small pieces of JavaScript, executed by WebSSH at the item's refresh interval (3 seconds by default, from 1 second to 10 minutes) while you are not typing. The code runs in a sandbox: there is no DOM, no require, and no network unless you turn on Network Access for the item. Only the objects described on this page are available.

What the script must return

Wrap your code in an immediately invoked function and return either:

  • a scalar (String, Number or Boolean): displayed as the label, the icon stays the one set in the settings (or the last one returned);
  • an Item Result Object (below);
  • undefined or null: the item is hidden until a later run returns a value.
(function() {
    return 'Hello!';
})();

Item Result Object

Property Type Description
label String, Number The text displayed in the State Bar. Numbers are converted to text. Falls back to an empty string.
icon String (optional) An SF Symbol name. When omitted, the last icon set is kept (the one from the settings on the first run).
tint3 String (optional) normal (default), success, warning or error. Colours the icon and the label (green, orange, red) and tints the item background, exactly like the Connection info item. Anything else is treated as normal. When the tint would not be readable on the bar of the current theme (a red tint on a red bar, for example), the item is drawn as an inverted pill instead: a background in the bar's text colour with the content in the tint colour.
badge3 Number, String (optional) A small capsule drawn on the top right corner of the icon, for counts (pending updates, alerts…). 0, an empty string or an absent value removes it.
progress3 Number (optional) 0 to 1. Replaces the icon with a small progress ring. Values outside the range are clamped.
unit3 String (optional) Unit of value, used by the graph of the details. bytes, bytes/s and bits/s are scaled and localized by WebSSH (12309214 → 12.3 MB/s); %, ms, s, °C and °F are appended to the number; any other short text is appended to a compact number (1250 with req/s → 1.25K req/s). Without a unit, large numbers are shown in compact form (12.3M).
parts3 Array (optional) A composition of a whole, drawn as a donut with a legend in the details of the item: [{ label: 'user', value: 35, unit: '%' }, { label: 'idle', value: 53, unit: '%' }]. At least two parts, values ≥ 0, unit optional (same values as above). The share of each part is computed from the sum.
detail3 String, Array of Strings (optional) Free text shown in the details of the item when it is tapped, in a fixed-width font: keep the bar short and put the list here (pending packages, failing units, every mount point…). An array is joined with line breaks. Limited to 8000 characters.
value3 Number (optional) The numeric value used by the sparkline. When omitted, the first number found in label is used.
(function() {
    return {
        label: '42 %',
        icon: 'gauge.with.dots.needle.50percent'
    };
})();

A tinted item with a progress ring and an explicit value:

(function() {
    let used = 85
    return {
        label: used + ' %',
        progress: used / 100,
        tint: used >= 90 ? 'error' : (used >= 75 ? 'warning' : 'normal'),
        value: used
    };
})();

Sparkline

The script has nothing to do for the sparkline: enable Graph in the item settings and WebSSH keeps the last 30 numeric values (from value, or the first number of label) and draws them next to the label.

Variables

Since WebSSH 32.10. A {{{ NAME : default }}} placeholder is replaced by the value set in the item editor before the script runs, so the script only ever sees plain text. Always put it inside a string literal; the value is escaped for JavaScript. See Variables for the syntax.

(function() {
    let city = '{{{ CITY : Paris }}}'
    let units = '{{{ UNITS : metric : imperial }}}'
    return city + ' (' + units + ')';
})();

$ssh

Function Returns Description
$ssh.exec(command) String or null Runs command on the remote server (SSH session) and returns its output. Returns null when the connection is down or the command fails. Avoid long running commands: wrap them with the Linux timeout command.
$ssh.isConnected() Boolean Whether the SSH connection is established.

mosh sessions

On a mosh session $ssh still exists for compatibility, but $ssh.exec always returns null (there is no SSH session any more once mosh-server is started, and the mosh protocol has no side channel). $ssh.isConnected() is true when the server answered recently. Use $mosh for the details.

$mosh

Available on mosh sessions only (since WebSSH 32.9). Test for it with typeof $mosh !== 'undefined'.

Function Returns Description
$mosh.state() String connecting, connected, stale (no recent contact), suspended or closed.
$mosh.isAlive() Boolean True while the session exists, including when stale or suspended.
$mosh.isConnected() Boolean True when the server answered recently.
$mosh.secondsSinceLastContact() Number Seconds since the last datagram from the server, -1 when the server was never heard.

$http

Since WebSSH 32.10. Only exists when Network Access is turned on for the item: test for it with typeof $http !== 'undefined'. Requests are sent by the device (not by the server), so $http works on mosh sessions too.

Function Returns Description
$http.get(url) Object or null Sends a GET request and waits for the response.
$http.get(url, options) Object or null Same, with options (below).

Options:

Property Type Description
headers Object (optional) Request headers, for example { Authorization: 'Bearer …', Accept: 'application/json' }.
timeout Number (optional) Seconds allowed for the whole request: 3 by default, from 1 to 5.

Response object:

Property Type Description
status Number The HTTP status code. A 404 or a 500 is a response, not a failure: check ok.
ok Boolean True when status is between 200 and 299.
body String The response body as text. Use JSON.parse(r.body) for JSON.
headers Object The response headers, names in lower case.
(function() {
    let r = $http.get('https://api.example.com/status', { headers: { Accept: 'application/json' } })
    if (!r || !r.ok) {
        return null;
    }
    return JSON.parse(r.body).status;
})();

$http.get returns null, and writes a console.warn explaining why, when:

  • the URL is not http or https;
  • the host is not in the Allowed Hosts of the item (exact host, or *.example.com for a domain and its subdomains; the port does not matter);
  • the server did not answer completely within the timeout, or the connection failed (DNS, TLS, self-signed certificate…);
  • the response is larger than 256 KB, or is not text.

A redirect is followed only when its target is also an allowed host; otherwise the redirect response itself (status 301, 302…) is returned, with a warning. No cookie, cache or credential is kept between two requests. The script waits for the response, and so does the State Bar: keep the timeout low and give the item a long refresh interval (10 seconds is the minimum with Network Access on).

eval is disabled

In a script with Network Access on, eval() and Function() throw an error: a downloaded text can be parsed (JSON.parse), never executed.

$terminal

Since WebSSH 30.5.

Function Returns Description
$terminal.getCols() Number The number of columns of the terminal.
$terminal.getRows() Number The number of rows of the terminal.

$vars

A small key / value store to keep data between two runs of your script, or to share data between items. It is not persistent: it is reset when the session ends.

Function Description
$vars.set(key, value) Stores value. The key is private to the item, unless it starts with GLOBAL_: it is then shared with every item of the session. Keys starting with WEBSSH_ are read-only, writing them is refused.
$vars.get(key) Returns the stored value, or undefined.
$vars.get(key, fallback) Returns the stored value, or fallback when the key is not set.

Any JSON compatible value can be stored (strings, numbers, booleans, arrays, objects).

WEBSSH_ variables

Read-only variables describing the current session, filled when the State Bar is created. They are available on every saved connection (SSH and mosh).

Key Example Description
WEBSSH_CONNECTION_NAME My SSH Server The name of the connection.
WEBSSH_CONNECTION_HOST ssh.example.com The host of the connection, as typed in the connection form.
WEBSSH_CONNECTION_USERNAME1 root The login user.
WEBSSH_CONNECTION_ICON2 server.rack The SF Symbol chosen as the connection icon.
WEBSSH_CONNECTION_ADDRESS 172.21.0.40 SSH only. The address handed to the SSH engine: the first resolved IP address, or the hostname itself when the DNS strategy of the connection is passthrough.
WEBSSH_CONNECTION_SERVER_IDENTIFIER SSH-2.0-OpenSSH_9.6 SSH only. The banner sent by the SSH server.

A missing variable returns undefined: always provide a fallback ($vars.get('WEBSSH_CONNECTION_ADDRESS', '')).

console

console.log, console.info, console.warn, console.error, console.debug and console.trace take a single string and write it to the WebSSH log, prefixed with the item identifier. Nothing is shown in the terminal. The easiest way to read them is the test panel, which lists them live.

Since WebSSH 33.0 they also feed the console of the State Bar: console.warn and console.error put an unread count on the item (or on the menu button when the item is hidden), and every level except debug and trace is listed in the console sheet and in the item details. Use warn for something the user should glance at without the item failing (a stale cache, a fallback used, a value out of the expected range), error for something they must fix, and keep log for plain traces: it never counts.

The log is a daily file stored in the WebSSH folder of the Files app (macOS: the app's Documents folder), kept for 7 days. It is only written when File Logger Level in Settings → Advanced Settings is not disabled; console.debug and console.trace need the Debug level, console.log and console.info the Info level.

Error handling

A JavaScript exception is listed in Items with Errors of the State Bar menu (see), written to the log (see console above) and, as the script returned nothing, the item is hidden until a later run succeeds. The test panel shows the message with its line and column. A malformed Item Result Object (for example an icon that is not a string) is logged too and the item keeps its previous content.


  1. Since WebSSH 29.6. ↩

  2. Since WebSSH 32.10. Before that version WEBSSH_CONNECTION_NAME, WEBSSH_CONNECTION_HOST and WEBSSH_CONNECTION_USERNAME were only filled on SSH sessions. ↩

  3. Since WebSSH 32.10. ↩↩↩↩↩↩↩


Last update: September 26, 2026