Skip to content

Source code

Browser terminal for SSH gateways

The reusable terminal uses xterm.js. It renders terminal output and input. Your backend authenticates users, authorizes targets, opens SSH, and owns the gateway protocol.

Start with your first page. Shared ui* providers are registered by createAdmin. Examples belong inside a route template, not the root HTML document. The page and its optional controller load through Atrium’s lazy route registry.

Minimal example

/**
* Integrate browser terminal for ssh gateways into an application-owned route.
*
* @author Laurent Declercq l.declercq@agon-innovation.ch
* @version 20260921
*/
import { terminalView } from '@agon/atrium/components/terminal';
/**
* Register a terminal connected to the application's gateway adapter.
*
* @param {object} context - Alpine and consumer service dependencies.
* @returns {void} Registers the terminal provider.
*/
export function register(context) {
context.Alpine.data('serverTerminal',
/**
* Create a terminal with an explicitly authorized transport.
*
* @returns {object} Terminal provider.
*/
() => terminalView({
/**
* Request a new terminal session through the application adapter.
*
* @param {object} handlers - Signal and terminal lifecycle callbacks.
* @returns {Promise<object>} Transport implementing send, resize, and close.
*/
connect: (handlers) => context.services.terminal.connect(handlers),
}));
}
<section x-data="serverTerminal">
<h1 tabindex="-1">Server terminal</h1>
<include src="{{ uiRoot }}/terminal.html"></include>
</section>

Settings and behavior

ContractMeaning
connect({ signal, onData, onClose, onError })Open one authorized gateway session and return its transport.
onData(stringOrUint8Array)Deliver decoded terminal output to xterm.
onClose()Report the remote session ending.
onError()Report a generic transport failure.
Returned send(data)Send terminal input to the backend using your protocol.
Returned resize({ cols, rows })Resize the remote pseudo-terminal.
Returned close()Release the gateway connection and handlers. Make this idempotent.
readOnlyOptional boolean disabling keyboard input, default false.
command('clear') / command('focus')Clear local rendering or focus the terminal.

The adapter must respect cancellation while connecting. It must close a partially established connection if initialization rejects. Late output is ignored, and a late successful connection is closed by Atrium. Container resizing fits the terminal and forwards dimensions. Theme changes update rendering colors. The terminal stays left-to-right inside an RTL application because terminal escape sequences and screen coordinates are directional.

The shared toolbar offers Enter fullscreen and Exit fullscreen. It expands the terminal and its toolbar using the browser Fullscreen API while preserving the connection and terminal contents. Resizing refits the terminal and forwards the new geometry to the gateway. Browser exit, including Escape, updates the control state. Route teardown exits only this terminal’s fullscreen session. Unsupported or denied fullscreen requests show a localized message and leave the connection usable.

Integration notes

There is no standard browser-to-SSH WebSocket framing. Implement the documented adapter against your own gateway rather than assuming the Proxmox protocol. Use TLS and short-lived authorization. Keep SSH passwords, tickets, and private keys out of localStorage and theme preferences. The offline showcase adapter is only a local echo demonstration and cannot execute commands. Never substitute it for a production backend. See the xterm API.

Working reference

See the production example. Return to the component index.

Author

Laurent Declercq l.declercq@agon-innovation.ch

License

Unless otherwise stated all source code is licensed under LGPL 2.1 and has the following copyright:

© 2026, Agon Partners Innovation AG, All rights reserved.

The design material and the “Agon Ātrium” trademark is the property of their authors. Reuse of them without prior consent of their respective authors is strictly prohibited.

Version

Version: 20260921