# grove.on()

## Signature

```ts
grove.on(type: string, callback: (payload: object) => void | Promise<void>): void
```

## Availability

All packaged runtimes can subscribe. The event's capability and scope determine whether useful data is delivered; subscribing grants no access.

## Parameters

| Parameter | Required | Description |
| --- | --- | --- |
| `type` | Yes | Exact case-sensitive event name. See the event reference. |
| `callback` | Yes | Function receiving one event payload. Keep its identity to remove it later. |

## Return value

Returns `undefined`; no unsubscribe function is returned.

## Behavior and errors

Listeners run in registration order. Registering the same function twice adds two subscriptions. Only `channels`, `channelSnapshots`, and `launch` retain their latest payload; a late subscriber receives that payload synchronously inside `on`. Other events are not replayed for a late listener.

Ordinary event delivery catches synchronous listener errors and logs them. It does not await returned Promises; handle asynchronous failures in your callback. `queryRenamed` is the exception: Mango awaits its listeners in sequence and retries failed delivery. Make rename handlers idempotent. Unknown event names do not produce an error or an event.

## Example

```js
function handleMessage(message) {
  if (message.own) return
  document.querySelector('#latest').textContent = message.text
}
grove.on('message', handleMessage)
// When this view no longer needs updates:
grove.off('message', handleMessage)
```

See [grove.off()](grove-off.md).

