> ## Documentation Index
> Fetch the complete documentation index at: https://prefab.prefect.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Call Handler

> Invoke a developer-registered JavaScript handler from a UI interaction.

`CallHandler` invokes a client-side JavaScript function registered by the app developer. Where `CallTool` crosses the network to your server, `CallHandler` runs instantly in the browser — ideal for state transformations like constraint enforcement, computed fields, or domain-specific logic that doesn't need server involvement.

```python theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
from prefab_ui.components import Slider
from prefab_ui.actions import CallHandler

Slider(name="infra", on_change=CallHandler("constrainBudget"))
```

Handlers are registered via `js_actions` on `PrefabApp`. See [Custom Handlers](/concepts/custom-handlers) for how to write and register them.

## Passing Arguments

Use `arguments` to pass extra data to the handler. Values support `{{ }}` interpolation, so you can pass client state at call time:

```python theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
from prefab_ui.components import Button
from prefab_ui.actions import CallHandler

Button("Recalculate", on_click=CallHandler(
    "recalculate",
    arguments={"mode": "aggressive", "total": "{{ budget }}"},
))
```

The handler receives these via `ctx.arguments`:

```javascript theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
// In js_actions
"recalculate": (ctx) => {
    const mode = ctx.arguments.mode;  // "aggressive"
    const total = ctx.arguments.total;  // resolved budget value
    // ... compute and return state updates
}
```

## Handling Results

The handler's return value is available as `$result` in `on_success` callbacks, just like `CallTool`:

```python theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
from prefab_ui.actions import CallHandler, ShowToast

Button("Validate", on_click=CallHandler(
    "validate",
    on_success=ShowToast("Valid!", variant="success"),
    on_error=ShowToast("Validation failed", variant="error"),
))
```

If the handler throws an exception, `on_error` fires with the error message in `$error`.

## Combined with Other Actions

Chain `CallHandler` with other actions in a list:

```python theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
from prefab_ui.actions import CallHandler, SetState

Slider(name="infra", on_change=[
    SetState("dirty", True),
    CallHandler("constrainBudget"),
])
```

## API Reference

<Card icon="code" title="CallHandler Parameters">
  <ParamField body="handler" type="str" required>
    Name of the registered handler function. Can be passed as a positional argument.
  </ParamField>

  <ParamField body="arguments" type="dict[str, Any] | None" default="None">
    Extra arguments passed to the handler via `ctx.arguments`. Values support `{{ key }}` interpolation.
  </ParamField>

  <ParamField body="on_success" type="Action | list[Action] | None" default="None">
    Action(s) to run when the handler returns. The return value is available as `$result`.
  </ParamField>

  <ParamField body="on_error" type="Action | list[Action] | None" default="None">
    Action(s) to run when the handler throws. The error message is available as `$error`.
  </ParamField>
</Card>

## Protocol Reference

```json CallHandler theme={"theme":{"light":"snazzy-light","dark":"dark-plus"}}
{
  "action": "callHandler",
  "handler": "string (required)",
  "arguments?": "object"
}
```

For the complete protocol schema, see [CallHandler](/protocol/call-handler).
