# Client Events (/docs/es_extended/events/client)

These are the `esx:` events on the client. Some are sent by the server to update the local player (load, job, money, inventory), others are fired locally by `es_extended` when something happens in the game (death, spawn, entering a vehicle). The tables show the arguments, who fires the event and whether you may trigger it yourself.

## Overview [#overview]

| | |
|---|---|
| Resource | `es_extended` |
| Side | Client |
| Server to client | Listen with `RegisterNetEvent(name, handler)` |
| Local client events | Listen with `AddEventHandler(name, handler)` |

| Marker | Meaning |
|---|---|
| **Secure** | Registered with [ESX.SecureNetEvent](/docs/es_extended/client/functions). ESX ignores it unless the server sent it. |
| **Not secured** | Plain `RegisterNetEvent` in ESX. Any client script (or injected cheat) can fire it locally with `TriggerEvent`. |
| **Local** | Fired by ESX on the client with `TriggerEvent`. Only listen. |

<Callout type="warn" title="Do not trigger ESX events yourself">
Triggering ESX state events (for example `esx:setJob` or `esx:setAccountMoney`) from your own client code only changes the local cache and confuses other scripts. Change data on the server with the [xPlayer](/docs/es_extended/server/xplayer) methods; ESX then sends the right events.
</Callout>

## Player lifecycle [#player-lifecycle]

### esx:playerLoaded [#esxplayerloaded]

**Sent by the server**, not secured. Fired once the character is loaded.

| Name | Type | Description |
|---|---|---|
| `xPlayer` | `table` | PlayerData table (see [Client PlayerData](/docs/es_extended/shared/playerdata)). |
| `isNew` | `boolean` | `true` for a newly created character. |
| `skin` | `table` | Saved skin. |

```lua title="client/main.lua"
RegisterNetEvent('esx:playerLoaded', function(xPlayer, isNew, skin)
    ESX.PlayerData = xPlayer

    if xPlayer.job.name == 'police' then
        CreatePoliceBlips()
    end
end)
```

### esx:onPlayerLogout [#esxonplayerlogout]

**Secure**, no arguments. Sent after the server logged the player out of the character (multicharacter). `ESX.PlayerLoaded` becomes `false`.

```lua
RegisterNetEvent('esx:onPlayerLogout', function()
    RemovePoliceBlips()
end)
```

### esx:onPlayerSpawn [#esxonplayerspawn]

**Local**, no arguments. Fired by ESX after the first spawn (non-multicharacter), and by other resources such as esx_multicharacter and esx_death after a character spawn or revive. ESX resets `PlayerData.dead`, restores saved health and armor on the first spawn and starts death detection.

```lua
AddEventHandler('esx:onPlayerSpawn', function()
    SetPedArmour(PlayerPedId(), 0)
end)
```

### esx:onPlayerDeath [#esxonplayerdeath]

**Local**, also sent to the server. Fired when ESX detects the death of the local ped.

| Field of `data` | Type | Description |
|---|---|---|
| `victimCoords` | `table` | `{ x, y, z }`. |
| `killedByPlayer` | `boolean` | Killed by another player. |
| `deathCause` | `number` | Weapon hash. |
| `killerCoords` | `table?` | Only for player kills. |
| `distance` | `number?` | Only for player kills. |
| `killerServerId` | `number?` | Only for player kills. |
| `killerClientId` | `number?` | Client player index of the killer. |

```lua
AddEventHandler('esx:onPlayerDeath', function(data)
    if data.killedByPlayer then
        ESX.ShowNotification(('You were killed by player %s'):format(data.killerServerId), 'error')
    end
end)
```

### esx:loadingScreenOff [#esxloadingscreenoff]

**Local**, no arguments. Fired after the first spawn when ESX shuts down the loading screen (non-multicharacter).

### esx:restoreLoadout [#esxrestoreloadout]

**Local**, internal. Removes all weapons and gives back the weapons, tints, components and ammo from `PlayerData.loadout`. ESX fires it after spawn and when skinchanger loads a new model. Built-in inventory only.

### esx:setPlayerData [#esxsetplayerdata]

**Local.** Fired by `ESX.SetPlayerData` with `(key, val, last)` for every PlayerData change. See [Client PlayerData](/docs/es_extended/shared/playerdata).

## Player data updates (server to client) [#player-data-updates-server-to-client]

All of these are **secure** and update `ESX.PlayerData` through `ESX.SetPlayerData`.

| Event | Arguments | Updates |
|---|---|---|
| `esx:setJob` | `job, lastJob` | `PlayerData.job` |
| `esx:jobDataRefreshed` | `job, lastJob` | `PlayerData.job` after a job definition changed |
| `esx:setGroup` | `group, lastGroup` | `PlayerData.group` |
| `esx:setAccountMoney` | `account` (`name`, `money`, `label`, `round`, `index`) | the matching entry in `PlayerData.accounts` |
| `esx:updatePlayerData` | `key, val` | any key, used for `metadata` and `variables` |
| `esx:setMaxWeight` | `maxWeight` | `PlayerData.maxWeight` |
| `esx:setInventory` | `inventory` | `PlayerData.inventory` |

```lua title="client/hud.lua"
RegisterNetEvent('esx:setAccountMoney', function(account)
    if account.name == 'money' then
        SendNUIMessage({ action = 'cash', value = account.money })
    end
end)

RegisterNetEvent('esx:setJob', function(job, lastJob)
    print(('Job changed from %s to %s'):format(lastJob.name, job.name))
end)
```

## Inventory and weapons (built-in inventory) [#inventory-and-weapons-built-in-inventory]

**Secure.** Not registered when `Config.CustomInventory` is set.

| Event | Arguments | Description |
|---|---|---|
| `esx:addInventoryItem` | `item, count, showNotification, itemData` | `count` is the **new total**. `itemData` has `label`, `weight`, `usable`, `rare`, `canRemove`. |
| `esx:removeInventoryItem` | `item, count, showNotification` | `count` is the new total, `0` removes the entry. |
| `esx:addLoadoutItem` | `weaponName, weaponLabel, ammo` | A weapon was added. |
| `esx:removeLoadoutItem` | `weaponName, weaponLabel` | A weapon was removed. |
| `esx:updateWeaponAmmo` | `weaponName, ammo` | Ammo changed on the server. |
| `esx:setWeaponTint` | `weaponName, tintIndex` | Applies a tint. |
| `esx:removeWeaponComponent` | `weaponName, componentName` | Removes a component. |
| `esx:showInventoryItemNotification` | `add, label, count` | Shows the item popup. |
| `esx:createPickup` | `pickupId, label, coords, itemType, name, components, tintIndex` | Spawns a ground pickup. |
| `esx:createMissingPickups` | `pickups` | Spawns pickups near the player. |
| `esx:removePickup` | `pickupId` | Deletes a pickup. |

```lua
RegisterNetEvent('esx:addInventoryItem', function(item, count)
    if item == 'radio' and count == 1 then
        ESX.ShowNotification('You can now use /radio')
    end
end)
```

## Notifications and commands (server to client) [#notifications-and-commands-server-to-client]

| Event | Arguments | Security |
|---|---|---|
| `esx:showNotification` | `message, type, length, title, position` | Not secured |
| `esx:showAdvancedNotification` | `sender, subject, msg, textureDict, iconType, flash, saveToBrief, hudColorIndex` | Not secured |
| `esx:showHelpNotification` | `msg, thisFrame, beep, duration` | Not secured |
| `esx:registerSuggestions` | `registeredCommands` | Secure |
| `esx:executeCommand` | `command` | Secure. Sent by `xPlayer.executeCommand`. |

The notification events are harmless if faked locally; they only display text. From the server prefer `xPlayer.showNotification(...)`.

## Admin events (server to client) [#admin-events-server-to-client]

These are sent by the admin commands. They are **not secured**, so a client-side script could fire them locally.

| Event | Arguments | Sent by |
|---|---|---|
| `esx:killPlayer` | none | `/kill` |
| `esx:freezePlayer` | `'freeze' \| 'unfreeze'` | `/freeze`, `/unfreeze` |
| `esx:repairPedVehicle` | none | `/repair` |
| `esx:tpm` | none | `/tpm`. Asks the server (`esx:isUserAdmin`) before teleporting. |
| `esx:noclip` | none | `/noclip`. Asks the server (`esx:isUserAdmin`) before toggling. |
| `esx:requestModel` | `model` | Loads a model. Not sent by es_extended itself. |

## Game state (local) [#game-state-local]

ESX checks these values in a loop every 500 ms (vehicle, pause menu) or through the esx_lib cache (ped, weapon) and fires local events.

| Event | Arguments | When |
|---|---|---|
| `esx:enteringVehicle` | `vehicle, plate, seat, netId` | The player starts entering a vehicle. Also sent to the server without `vehicle`. |
| `esx:enteringVehicleAborted` | none | The enter attempt was cancelled. Also sent to the server. |
| `esx:enteredVehicle` | `vehicle, plate, seat, displayName, netId` | The player is in the vehicle. Also sent to the server without `vehicle`. |
| `esx:exitedVehicle` | `vehicle, plate, seat, displayName, netId` | The player left the vehicle or died in it. Also sent to the server without `vehicle`. |
| `esx:vehicleSeatChanged` | `seat` | Seat changed inside the same vehicle. |
| `esx:pauseMenuActive` | `isActive` | Pause menu opened or closed. |
| `esx:playerPedChanged` | `ped` | The player ped handle changed (model change, respawn). |
| `esx:weaponChanged` | `weapon` | Selected weapon hash changed. |

`plate` is the raw plate text with padding; trim it with `ESX.Math.Trim`. `netId` is the local handle when the vehicle is not networked.

```lua title="client/main.lua"
AddEventHandler('esx:enteredVehicle', function(vehicle, plate, seat)
    if seat == -1 then
        ESX.ShowNotification(('Driving %s'):format(ESX.Math.Trim(plate)))
    end
end)

AddEventHandler('esx:pauseMenuActive', function(isActive)
    SendNUIMessage({ action = 'hud', visible = not isActive })
end)
```

## Deprecated and removed [#deprecated-and-removed]

| Event | Status |
|---|---|
| `esx:getSharedObject` | Deprecated. Use `exports['es_extended']:getSharedObject()` or the imports file. |
| `esx:addWeapon`, `esx:addWeaponComponent`, `esx:setWeaponAmmo`, `esx:removeWeapon` | Removed. Triggering them raises an error. Use `xPlayer.addWeapon`, `xPlayer.addWeaponComponent`, `xPlayer.addWeaponAmmo` and `xPlayer.removeWeapon` on the server. |
| `esx:playerJumping` | Removed. Not fired in 1.16. |

## Related [#related]

- [Server events](/docs/es_extended/events/server)
- [Client PlayerData](/docs/es_extended/shared/playerdata)
- [Client functions](/docs/es_extended/client/functions)
- [xPlayer](/docs/es_extended/server/xplayer)
