# Client UI (/docs/es_extended/client/ui)

The client UI functions show feedback to the player: GTA notifications and help text, the ESX notify, TextUI, progress bar and context menu resources, and the classic `ESX.UI.Menu` system used by older menu resources. All of them run on the client.

## Overview [#overview]

| | |
|---|---|
| Resource | `es_extended` |
| Side | Client |
| Source | `client/modules/ui/*.lua` |
| Optional dependencies | `esx_notify`, `esx_textui`, `esx_progressbar`, `esx_context`, menu resources |

`ESX.ShowNotification`, `ESX.TextUI`, `ESX.Progressbar` and the context functions call exports of separate resources. If the resource was not present when `es_extended` started, the call raises `Resource [name] is Missing!`.

## Notifications [#notifications]

### ESX.ShowNotification [#esxshownotification]

```lua
ESX.ShowNotification(message, notifyType, length, title, position)
```

Shows a notification through `esx_notify`.

| Name | Type | Description |
|---|---|---|
| `message` | `string` | Text. `~br~` becomes a line break. |
| `notifyType` | `string?` | `info` (default), `success`, `error` or `warning`. |
| `length` | `number?` | Duration in milliseconds. Default `5000`. |
| `title` | `string?` | Title. esx_notify shows "New Notification" when empty. |
| `position` | `string?` | `top-right`, `top-left`, `top-middle`, `bottom-right`, `bottom-left`, `bottom-middle`, `middle-left` or `middle-right`. Falls back to the esx_notify config. |

**Returns:** nothing

```lua
ESX.ShowNotification('Vehicle stored in the garage', 'success', 4000, 'Garage')
```

From the server, use `xPlayer.showNotification(...)` or trigger `esx:showNotification` with the same arguments.

### ESX.ShowAdvancedNotification [#esxshowadvancednotification]

```lua
ESX.ShowAdvancedNotification(sender, subject, msg, textureDict, iconType, flash, saveToBrief, hudColorIndex)
```

Shows a native GTA feed notification with a picture, like a phone message.

| Name | Type | Description |
|---|---|---|
| `sender` | `string` | Title line. |
| `subject` | `string` | Subtitle line. |
| `msg` | `string` | Message body. |
| `textureDict` | `string` | Texture dictionary of the picture, for example `CHAR_BANK_MAZE`. Used as dictionary and texture name. |
| `iconType` | `number` | Small icon next to the title (`1` chat, `2` email, `3` friend request, `7` arrow, `8` RP, `9` dollar). |
| `flash` | `boolean` | Passed to the ticker native. |
| `saveToBrief` | `boolean?` | Store in the pause menu brief. Default `true`. |
| `hudColorIndex` | `number?` | Background [HUD color](https://docs.fivem.net/docs/game-references/hud-colors/). |

**Returns:** nothing

```lua
ESX.ShowAdvancedNotification('Maze Bank', 'Transfer', 'You received $2,500', 'CHAR_BANK_MAZE', 9, false, true, 140)
```

### ESX.ShowHelpNotification [#esxshowhelpnotification]

```lua
ESX.ShowHelpNotification(msg, thisFrame, beep, duration)
```

Shows the black help box in the top left corner.

| Name | Type | Description |
|---|---|---|
| `msg` | `string` | Text. Input tokens such as `~INPUT_CONTEXT~` work. |
| `thisFrame` | `boolean?` | Show only for the current frame. Call it every frame in a loop. |
| `beep` | `boolean?` | Play the beep sound. Default `true`. Ignored with `thisFrame`. |
| `duration` | `number?` | Duration in ms. Default `-1` (until replaced). Ignored with `thisFrame`. |

**Returns:** nothing

```lua
CreateThread(function()
    while isNearShop do
        ESX.ShowHelpNotification('Press ~INPUT_CONTEXT~ to open the shop', true)
        Wait(0)
    end
end)
```

### ESX.ShowFloatingHelpNotification [#esxshowfloatinghelpnotification]

```lua
ESX.ShowFloatingHelpNotification(msg, coords)
```

Shows a help bubble anchored at a world position. Call it every frame.

| Name | Type | Description |
|---|---|---|
| `msg` | `string` | Text. |
| `coords` | `vector3` | World position. |

**Returns:** nothing

```lua
local shop = vector3(25.7, -1347.3, 29.5)

CreateThread(function()
    while true do
        local sleep = 500
        if #(GetEntityCoords(ESX.PlayerData.ped) - shop) < 3.0 then
            sleep = 0
            ESX.ShowFloatingHelpNotification('Shop', shop)
        end
        Wait(sleep)
    end
end)
```

### ESX.DrawMissionText [#esxdrawmissiontext]

```lua
ESX.DrawMissionText(msg, time)
```

Shows subtitle text at the bottom of the screen, like mission instructions.

| Name | Type | Description |
|---|---|---|
| `msg` | `string` | Text. |
| `time` | `number` | Duration in milliseconds. |

**Returns:** nothing

```lua
ESX.DrawMissionText('Deliver the package to ~y~Sandy Shores~s~', 6000)
```

### ESX.UI.ShowInventoryItemNotification [#esxuishowinventoryitemnotification]

```lua
ESX.UI.ShowInventoryItemNotification(add, item, count)
```

Shows the small "+1 Bread" / "-1 Bread" item popup of the built-in inventory UI. The server triggers it through the secure event `esx:showInventoryItemNotification`.

| Name | Type | Description |
|---|---|---|
| `add` | `boolean` | `true` for added, `false` for removed. |
| `item` | `string` | Label to display. |
| `count` | `number` | Amount. |

**Returns:** nothing

## TextUI [#textui]

### ESX.TextUI [#esxtextui]

```lua
ESX.TextUI(message, notifyType)
```

Shows a persistent text box through `esx_textui` until you hide it.

| Name | Type | Description |
|---|---|---|
| `message` | `string` | Text to show. |
| `notifyType` | `string?` | Style, default `info`. |

**Returns:** nothing

### ESX.HideUI [#esxhideui]

```lua
ESX.HideUI()
```

Hides the TextUI box.

```lua
local point = ESX.Point:new({
    coords = vector3(441.0, -981.0, 30.7),
    distance = 2.0,
    enter = function()
        ESX.TextUI(('[%s] Open armory'):format(ESX.GetInteractKey()))
    end,
    leave = function()
        ESX.HideUI()
    end,
})
```

## Progress bar [#progress-bar]

### ESX.Progressbar [#esxprogressbar]

```lua
ESX.Progressbar(message, length, options)
```

Starts a progress bar through `esx_progressbar`. Only one can run at a time.

| Name | Type | Description |
|---|---|---|
| `message` | `string` | Label. |
| `length` | `number?` | Duration in ms. Default `3000`. |
| `options` | `table?` | See below. |

| Option | Type | Description |
|---|---|---|
| `FreezePlayer` | `boolean?` | Freeze the ped while running. |
| `animation` | `table?` | `{ type = 'anim', dict = '...', lib = '...' }` or `{ type = 'Scenario', Scenario = '...' }`. |
| `onFinish` | `function?` | Called when the bar completes. |
| `onCancel` | `function?` | Called when the bar is cancelled. |

**Returns:** `boolean`, `false` if another progress bar is running.

```lua
ESX.Progressbar('Repairing vehicle', 8000, {
    FreezePlayer = true,
    animation = { type = 'Scenario', Scenario = 'PROP_HUMAN_BUM_BIN' },
    onFinish = function()
        TriggerServerEvent('mechanic:repairDone')
    end,
    onCancel = function()
        ESX.ShowNotification('Repair cancelled', 'error')
    end,
})
```

### ESX.CancelProgressbar [#esxcancelprogressbar]

```lua
ESX.CancelProgressbar()
```

Cancels the running progress bar and calls its `onCancel`.

## Context menu [#context-menu]

These wrap the `esx_context` exports. ESX strips HTML tags from the `title`, `description`, `label` and `inputPlaceholder` fields of every element before it opens or refreshes the menu. Element format and callbacks are documented on [esx_context](/docs/core/esx_context).

### ESX.OpenContext [#esxopencontext]

```lua
ESX.OpenContext(position, elements, onSelect, onClose, canClose)
```

| Name | Type | Description |
|---|---|---|
| `position` | `string` | `left`, `center` or `right`. |
| `elements` | `table[]` | Menu elements. |
| `onSelect` | `function?` | `function(menu, element)` when an element is selected. |
| `onClose` | `function?` | `function(menu)` when the menu closes. |
| `canClose` | `boolean?` | Whether the player may close it with Escape. Default `true`. |

```lua
ESX.OpenContext('right', {
    { unselectable = true, icon = 'fas fa-car', title = 'Garage' },
    { icon = 'fas fa-warehouse', title = 'Store vehicle', value = 'store' },
    { icon = 'fas fa-key', title = 'Take out vehicle', value = 'take' },
}, function(menu, element)
    if element.value == 'store' then
        StoreVehicle()
    end
    ESX.CloseContext()
end)
```

### ESX.PreviewContext [#esxpreviewcontext]

```lua
ESX.PreviewContext(position, elements, onSelect, onClose, canClose)
```

Opens the context menu as a preview without taking NUI focus.

### ESX.CloseContext [#esxclosecontext]

```lua
ESX.CloseContext()
```

Closes the open context menu.

### ESX.RefreshContext [#esxrefreshcontext]

```lua
ESX.RefreshContext(elements, position)
```

Replaces the elements of the open context menu.

## ESX.UI.Menu [#esxuimenu]

`ESX.UI.Menu` is the classic menu API. Menu resources such as [esx_menu_default](/docs/core/esx_menu_default), [esx_menu_dialog](/docs/core/esx_menu_dialog) and [esx_menu_list](/docs/core/esx_menu_list) register a type, and scripts open menus of that type.

### ESX.UI.Menu.RegisterType [#esxuimenuregistertype]

```lua
ESX.UI.Menu.RegisterType(menuType, open, close)
```

| Name | Type | Description |
|---|---|---|
| `menuType` | `string` | Type key, for example `default` or `dialog`. |
| `open` | `function` | `function(namespace, name, data)` that renders the menu. |
| `close` | `function` | `function(namespace, name)` that hides it. |

**Returns:** nothing

### ESX.UI.Menu.Open [#esxuimenuopen]

```lua
ESX.UI.Menu.Open(menuType, namespace, name, data, submit, cancel, change, close)
```

| Name | Type | Description |
|---|---|---|
| `menuType` | `string` | Registered type. |
| `namespace` | `string` | Usually `GetCurrentResourceName()`. Menus of a stopped resource are closed automatically. |
| `name` | `string` | Menu name, unique within the namespace. |
| `data` | `table` | Menu data, for example `title`, `align`, `elements`. |
| `submit` | `function?` | `function(data, menu)` when an element is selected. |
| `cancel` | `function?` | `function(data, menu)` when the player backs out. |
| `change` | `function?` | `function(data, menu)` when the selection or a value changes. |
| `close` | `function?` | Called after `menu.close()`. |

**Returns:** the menu object with `type`, `namespace`, `resourceName`, `name`, `data` and these methods:

| Method | Description |
|---|---|
| `menu.close()` | Close this menu. |
| `menu.update(query, newData)` | Merge `newData` into every element that matches all keys of `query`. |
| `menu.refresh()` | Re-render with the current `menu.data`. |
| `menu.setElement(i, key, val)` | Set one key on element `i`. |
| `menu.setElements(elements)` | Replace all elements. |
| `menu.setTitle(title)` | Change the title. |
| `menu.removeElement(query)` | Remove the first element that matches a key of `query`. |

After `update`, `setElement`, `setElements`, `setTitle` or `removeElement`, call `menu.refresh()` to show the change.

```lua
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory', {
    title = 'Armory',
    align = 'top-left',
    elements = {
        { label = 'Pistol', value = 'WEAPON_PISTOL' },
        { label = 'Nightstick', value = 'WEAPON_NIGHTSTICK' },
    },
}, function(data, menu)
    TriggerServerEvent('police:takeWeapon', data.current.value)
    menu.close()
end, function(data, menu)
    menu.close()
end)
```

### ESX.UI.Menu.Close [#esxuimenuclose]

```lua
ESX.UI.Menu.Close(menuType, namespace, name, cancel)
```

Closes a specific menu. With `cancel = true` the menu's `cancel` callback runs instead of `close`.

### ESX.UI.Menu.CloseAll [#esxuimenucloseall]

```lua
ESX.UI.Menu.CloseAll(cancel)
```

Closes every open menu. With `cancel = true`, each menu's `cancel` callback runs.

### ESX.UI.Menu.GetOpened [#esxuimenugetopened]

```lua
ESX.UI.Menu.GetOpened(menuType, namespace, name)
```

**Returns:** the menu object, or `nil` if it is not open. `ESX.UI.Menu.IsOpen` is an alias, so it also returns the menu (truthy) or `nil`.

```lua
if ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'armory') then
    ESX.UI.Menu.Close('default', GetCurrentResourceName(), 'armory')
end
```

### ESX.UI.Menu.GetOpenedMenus [#esxuimenugetopenedmenus]

```lua
ESX.UI.Menu.GetOpenedMenus()
```

**Returns:** the internal array of open menus (`ESX.UI.Menu.Opened`). Closed menus leave `nil` holes, so iterate with `pairs`.

## Common issues [#common-issues]

- **"Resource [esx_context] is Missing!"**: the helper resource is not installed or starts after `es_extended`. Fix the start order in `server.cfg`.
- **Menu does not open**: no resource registered the menu type. Start the matching menu resource.
- **HTML in context titles disappears**: ESX strips tags on purpose. Use plain text.

## Related [#related]

- [Client functions](/docs/es_extended/client/functions)
- [esx_notify](/docs/core/esx_notify)
- [esx_textui](/docs/core/esx_textui)
- [esx_progressbar](/docs/core/esx_progressbar)
- [esx_context](/docs/core/esx_context)
