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

# onTrigger

> Subscribe to chat trigger events and run client-side actions.

```javascript theme={null}
Hacktionbase.onTrigger(handler)
Hacktionbase.onTrigger(key, handler)
```

Subscribes to **chat trigger** events forwarded from the widget. Whenever a trigger is executed (the user clicked the CTA proposed by the chatbot), the handler runs in your host page with the extracted data.

Returns an `unsubscribe` function. Call it to remove the listener.

## Parameters

<ParamField body="key" type="string">
  Optional. Scope the handler to a single trigger key. Omit to receive every executed trigger.
</ParamField>

<ParamField body="handler" type="(event: TriggerEvent) => void" required>
  Called once per matched execution. The event payload is described below.
</ParamField>

## Event shape

```typescript theme={null}
interface TriggerEvent {
  id: string;                       // Trigger document ID
  key: string;                      // Stable trigger key (e.g. "create_project")
  data: Record<string, string>;     // Fields extracted from the user message
  executionEventId: string;         // Unique ID for this execution (dedupe)
  userId: string | null;            // Set only when the session is identified
  anonymousId: string;              // Always present — the session identity
  occurredAt: string;               // ISO timestamp
  context: {
    tenantId: string;
    userId: string | null;          // Same as top-level userId
    anonymousId: string;            // Same as top-level anonymousId
    accountId: string | null;       // Current account (via identify({ account }))
  };
}
```

The session is always identified by `anonymousId`. When the user has been
identified via `Hacktionbase.identify()`, `userId` is **also** set; otherwise
it is `null`. To distinguish an identified vs. anonymous session, check whether
`userId` is non-null.

## Examples

### Listen for a single trigger

```javascript theme={null}
const unsubscribe = Hacktionbase.onTrigger('open_billing', (event) => {
  window.location.href = '/billing';
});

// Later, when you no longer need the handler
unsubscribe();
```

### Prefill a form from extracted data

```javascript theme={null}
Hacktionbase.onTrigger('create_project', (event) => {
  const { name, plan } = event.data;
  document.querySelector('#project-name').value = name ?? '';
  document.querySelector('#project-plan').value = plan ?? 'starter';
  Hacktionbase.close();
});
```

### Catch every trigger (e.g. for analytics)

```javascript theme={null}
Hacktionbase.onTrigger((event) => {
  analytics.track('chat_trigger_fired', {
    key: event.key,
    executionEventId: event.executionEventId
  });
});
```

## Security

* Trigger events are scoped to the **current session**. Your handler will never receive an event from another user.
* The same `executionEventId` is delivered to your backend webhook — use it to correlate the two, or to deduplicate retries.
* For sensitive actions, prefer running the side effect in your backend webhook (where you can verify the HMAC signature) and use `onTrigger` only for UI side effects (redirect, prefill, toast).

## Related

* See [Chat Triggers](/widget/triggers) to learn how to configure triggers in the dashboard.
* See [Trigger pipeline](/concepts/triggers) for the end-to-end architecture.
