Output
VPN service names and statuses, such as Tailscale connected, Work connecting, with a state-dependent icon. The default label sorts services by name and omits disconnected services. With no active services, the item shows VPN disconnected. Omitting the vpn block behaves the same as vpn: {}.
Failed reads show VPN unavailable, or the affected service’s name followed by unavailable. Known active names remain visible when another service cannot be read.
Example
{
"id": "vpn",
"type": "vpn",
"vpn": {
"hideWhenDisconnected": true,
"tints": {
"connected": "#A6DA95",
"connecting": "#EED49F",
"unavailable": "#ED8796"
}
}
}
This hides the item only when all detected services are disconnected, including when no services are registered. Connecting, disconnecting, and unavailable states remain visible.
Configuration
Use the item-level text template to customise or hide the label. The provider options below control its data, symbols, colours, and visibility.
All fields below are inside vpn.
| Property | Default | Description |
|---|---|---|
showSymbol | true | Show the state icon; false hides even an item-level symbol override. |
hideWhenDisconnected | false | Hide only a confirmed disconnected state. Failed reads remain visible. |
symbols.font | - | Shared installed font name for glyph symbols; each glyph can override it. |
symbols.size | Resolved item/theme font size | Shared glyph size, 8 to 72 points; each glyph can override it. |
symbols state keys | Icons below | Override symbols for the five connection states. |
tints state keys | Normal tint | State colours for the same five states; accept #RRGGBB or #RRGGBBAA. |
Connection states
symbols and tints accept these state keys:
| State key | Default symbol | Default label |
|---|---|---|
connecting | arrow.triangle.2.circlepath | connecting |
connected | lock.shield.fill | connected |
disconnecting | arrow.triangle.2.circlepath | disconnecting |
disconnected | lock.shield | disconnected |
unavailable | exclamationmark.shield | unavailable |
With multiple services, the overall icon, tint, and aggregate label use the first present state in this order: unavailable, connected, connecting, disconnecting, disconnected. Each visible service keeps its own status label.
Use a services loop with state conditions to customise each service label. Use text: "VPN {{status}}" for an aggregate label or text: "" for an icon alone. Accessibility retains the native names and statuses.
Symbols and colours
Symbols accept SF Symbol names or font glyph objects. Use symbolFontWeight to set SF Symbol weight independently of text.
An item-level symbol overrides the state icon; showSymbol: false hides it regardless. Omitted state symbols use the built-in defaults. State tints override the normal item/theme tint.
To change vpn, edit the configuration file. sbar set cannot change this block.
Shared item options cover styling, symbols, actions, priority, and enabled state.
Text templates
The item-level text setting supports id, value, symbol, status, names, connected, available, services, name, serviceId, index, total, first, last, separator. See service and device loops for field meanings and examples. names contains active service names, sorted and comma-separated. The services loop includes all monitored services, including disconnected ones. An unavailable service list is empty.
Inside the loop, value, status, and connected describe that entry; outside, they describe the aggregate state. Entry-only fields are empty outside the loop. Loops retain the aggregate symbol, tint, and hide rules.
Updates
Items and displays share one native event monitor. The provider uses SystemConfiguration service and connection notifications and retries unavailable reads every two seconds.
Refresh policies capture service states, text, icon, tint, and visibility together. Interval and manual items hold their snapshot until refreshed or triggered. Triggers capture the latest shared state. See refresh policies.
Current limits
Detects enabled Network Extension, IPSec, and L2TP VPN services registered with macOS. Standalone tunnels that do not register a macOS service are outside its coverage. There is no service filter or built-in connect/disconnect control.
A connected state reports the service’s status. It does not establish whether all traffic uses the VPN or whether the remote network is reachable. Use the Network provider for the active network connection type.