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

# Events

> Server and client events fxChat fires and listens to.

Hook into chat events from your own scripts.

## Server-side

### `chatMessage` (legacy, compatible)

Standard FiveM event — backwards-compatible.

```lua Server theme={null}
AddEventHandler('chatMessage', function(source, name, message)
    -- triggered for every message sent
end)
```

<ParamField path="source" type="number">
  The sender's server ID.
</ParamField>

<ParamField path="name" type="string">
  Sender display name (character name in roleplay, Steam name otherwise).
</ParamField>

<ParamField path="message" type="string">
  Raw message text (after color-code parsing).
</ParamField>

<Note>
  Raw strings only. For rich payloads use `fxChat:messageReceived` below.
</Note>

***

### `fxChat:messageReceived`

Rich message event with the full options payload.

```lua Server theme={null}
AddEventHandler('fxChat:messageReceived', function(source, payload)
    -- payload.args, payload.title, payload.label, payload.color, etc.
end)
```

<ParamField path="source" type="number">
  Sender server ID.
</ParamField>

<ParamField path="payload" type="object">
  Same shape as the `options` argument of
  [`addMessage`](/docs/fxchat/exports/server#addmessage-target-options) — `args`,
  `title`, `label`, `color`, `badge`, `special`.
</ParamField>

```lua Example — log to your own analytics theme={null}
AddEventHandler('fxChat:messageReceived', function(source, payload)
    MyAnalytics:track('chat_message', {
        playerId = source,
        message = payload.args,
        author = payload.title,
    })
end)
```

***

### `fxChat:playerMuted`

Fired when a player is muted (manually or auto-muted by rate limiter).

```lua Server theme={null}
AddEventHandler('fxChat:playerMuted', function(source, durationMs, reason)
    -- ...
end)
```

<ParamField path="source" type="number">
  Server ID of the muted player.
</ParamField>

<ParamField path="durationMs" type="number | nil">
  Mute duration in ms, or `nil` for permanent.
</ParamField>

<ParamField path="reason" type="string">
  `"manual"`, `"rate_limit"`, or `"blacklist"`.
</ParamField>

***

### `fxChat:playerUnmuted`

Fired when a mute expires or is lifted.

```lua Server theme={null}
AddEventHandler('fxChat:playerUnmuted', function(source)
    -- ...
end)
```

***

## Client-side

### `fxChat:opened`

Fired when the chat input becomes focused (T pressed).

```lua Client theme={null}
AddEventHandler('fxChat:opened', function()
    -- pause your minigame, hide HUD, etc.
end)
```

***

### `fxChat:closed`

Fired when chat input loses focus (ESC pressed or message sent).

```lua Client theme={null}
AddEventHandler('fxChat:closed', function()
    -- resume normal HUD
end)
```

***

### `fxChat:themeChanged`

Fired when the active theme changes for this client (player picked a new
one, or admin force-changed it).

```lua Client theme={null}
AddEventHandler('fxChat:themeChanged', function(themeName)
    print('Theme is now:', themeName)
end)
```

<ParamField path="themeName" type="string">
  Filename without `.json` (e.g. `"midnight"`).
</ParamField>

***

## Triggering events from your code

For most cases use the [exports](/docs/fxchat/exports/server) — but you can
trigger these events manually if you need to.

```lua theme={null}
TriggerEvent('fxChat:playerMuted', source, 60000, 'manual')
```

<Warning>
  Triggering `fxChat:messageReceived` notifies listeners but doesn't
  broadcast. Use [`addMessage`](/docs/fxchat/exports/server#addmessage-target-options)
  to send a real message.
</Warning>
