Skip to main content

React Hooks

@qontinui/ui-bridge exports 33 React hooks from @qontinui/ui-bridge/react. This page is the index; each family has its own reference page.

Every hook on these pages was written against the implementation in packages/ui-bridge/src/react/. Where a hook's own doc comment and its code disagree, the pages say so explicitly rather than repeating the comment.

Hook index​

Element & component registration​

Attach a DOM node or a logical component to the registry so automation can see and drive it. → Registration hooks

HookWhat it does
useUIElementRegister a DOM element and get a ref, trigger, state accessors
useUIElementRefDeprecated no-op — kept for source compatibility
useUIComponentRegister a component with named, high-level actions
useUIComponentActionMemoize an action handler (a typed useCallback)
useOwningComponentRead the enclosing UIBridgeComponentScope id

Auto-registering a whole subtree instead of hook-by-hook is useAutoRegister, which has its own page.

The model: states, transitions, navigation​

UI Bridge models an app as states connected by transitions, and navigates between them by pathfinding. The concepts are explained in State Machine Integration; the pages below are the reference for the hooks that implement them. States are declared by the app — useUIState registers one — and observed at runtime with useActiveStates and useStateSnapshot.

HookWhat it does
useUIStateRegister one state; activate / deactivate / toggle it
useUIStateGroupRegister a group of states that activate atomically
useActiveStatesSubscribe to the active-state id list
useStateSnapshotRead all states, groups and transitions at once
useUITransitionRegister a transition; canExecute + execute()
useTransitionsRead every registered transition
useAvailableTransitionsSubscribe to the transitions executable right now
useUINavigationfindPath() / navigateTo() across the state graph
useCanNavigateToBoolean "is there a path to these states?"
useNavigationPathThe PathResult for a target, without executing it

→ State hooks · Transition hooks · Navigation hooks

Semantic declaration​

Tell the bridge things the DOM cannot express — what an element is for, how elements relate, what can be dragged where. → Semantic hooks

HookWhat it does
useUIAnnotationAttach description / purpose / tags to an element id
useUIRelationshipDeclare one typed relationship between two elements
useUIRelationshipsDeclare many relationships from one source element
useDragSourceMark an element as draggable, with a data type
useDropZoneMark an element as a drop target, with accepted types

The drag-and-drop model itself is described in Drag & Drop.

App context & capabilities​

Page identity, routing, keyboard shortcuts and undo state — the app-level context that ends up in a snapshot. → App-context hooks

HookWhat it does
usePageContextName the current page / section / breadcrumb
useRouteAwarenessFeed router pattern, params and query into the tracker
useKeyboardShortcutsPublish the shortcuts your app implements
useUndoRedoDeclare authoritative undo/redo state, overriding heuristics

Bridge access​

Reach the provider's context, registry and executor from anywhere in the tree. → Bridge-access hooks

HookWhat it does
useUIBridgeThe main façade: elements, components, workflows, actions, snapshots
useUIBridgeRequiredSame, but throws when there is no provider
useUIBridgeContextRaw context value; throws outside a provider
useUIBridgeOptionalRaw context value or null
useUIBridgeWindowLabelThe enclosing window label in multi-window hosts

Host integration​

Wiring the SDK to a relay, an iframe host, or a deploy that ships new bundles. → Integration hooks

HookWhat it does
useCommandRelayConnect the browser to the server command relay over SSE
useUIBridgeEchoEcho arbitrary JSON state into the snapshot via a hidden input
useBuildIdWatcherDetect that the server shipped a new bundle

Best practices​

1. Give elements stable, descriptive ids​

The id is the automation contract. Rename a component freely; renaming its UI Bridge id breaks every script that targeted it.

// Good
useUIElement({ id: 'checkout-submit-button' });
useUIComponent({ id: 'user-profile-form', name: 'User Profile Form' });

// Avoid
useUIElement({ id: 'btn1' });
useUIComponent({ id: 'form', name: 'Form' });

2. Do not hand-write data-ui-id​

data-ui-id is legacy and is no longer read. useUIElement stamps data-ui-bridge-id on the node itself once the ref attaches, and identification otherwise goes through the registry. The hook that used to write the old attribute, useUIElementRef, is a deprecated no-op.

3. Let unmount do the cleanup​

Nearly every hook here registers on mount and unregisters on unmount. The one deliberate exception is called out on its page: useUIAnnotation, which persists across unmount on purpose.

4. Type your action parameters​

interface LoginParams {
email: string;
password: string;
}

useUIComponent({
id: 'login-form',
name: 'Login Form',
actions: [
{
id: 'login',
paramSchema: { email: 'string', password: 'string' },
handler: async (params?: LoginParams) => login(params!.email, params!.password),
},
],
});

paramSchema is surfaced verbatim on /control/component/:id so a caller can discover the shape without reading your source, and the SDK checks params against it before your handler runs. Two forms are accepted: the map shorthand above, and a JSON-Schema-subset object ({ type: 'object', properties, required, additionalProperties }) — the shape paramSchemaOf() (@qontinui/ui-bridge-wrapper) emits.

The gate starts in 'warn' mode: violations are logged and the handler still runs. Arm it per deployment with setDefaultParamValidationMode('enforce'), after which a violating call comes back as success: false with failureDetails.errorCode === 'UB-ACTION-REJECTED' and failureDetails.invalidParams naming each offending param. A single call can override the mode through executeComponentAction's { paramValidation } option bag; the wire cannot, deliberately — enforcement is the deployment's policy, not the validated caller's to switch off.

In map form a bare string is read as a type hint only when it is one of the seven JSON Schema primitive names (string, number, integer, boolean, object, array, null). Any other string is prose and constrains nothing, so { count: 'number (>= 1, defaults to 1)' } stays a human-readable hint rather than becoming an unsatisfiable rule. Map form also never marks a param required — it has no way to express optionality. Write the object form if you need required.

5. Give a long-running action a timeout​

An AbortSignal cannot be JSON-serialized, so timeoutMs on the request is the only way an out-of-process caller can call off a hung handler:

await bridge.executeComponentAction('login-form', {
action: 'login',
params: { email, password },
timeoutMs: 5_000,
});

The executor races the handler promise, so abandonment does not depend on your handler observing the signal it is passed. On abandonment the response is success: false with failureDetails.errorCode === 'UB-ACTION-TIMEOUT' and failureDetails.cancelReason === 'timeout'. An in-process caller can pass its own { signal } instead — that arm reports 'UB-ACTION-FAILED' with cancelReason === 'signal', so cancelReason rather than the code is the reliable "was this abandoned?" test.

Your handler receives the signal as the second argument, which is how it releases its own in-flight work instead of leaving it detached:

handler: async (params, { signal }) => fetch(url, { signal }),