# Agent UI

URL: https://better-helpdesk.com/docs/inbox/agent-ui/

HelpdeskAdmin's props, its sections and URLs, its keyboard shortcuts, and the CSS custom properties it reads.



`better-helpdesk/admin` exports the agent UI, `HelpdeskAdmin`, and two constants. The module starts with `'use client'`. The UI calls the [`agent/*` routes](/docs/reference/routes#agent), which answer only an agent. Related guide: [Theme the widget and the agent UI](/docs/customize/theming).

```tsx title="app/helpdesk/[[...slug]]/page.tsx"
import { HelpdeskAdmin } from 'better-helpdesk/admin';

export default function Page() {
  return <HelpdeskAdmin api="/api/helpdesk" basePath="/helpdesk" locale="en" />;
}
```

## Props [#props]

<TypeTable
  type="{
  basePath: {
    type: 'string',
    required: true,
    description: <>Where the agent UI is mounted, such as <code>/helpdesk</code>. Its screens are paths under it.</>,
  },
  locale: {
    type: &#x22;'en' | 'de' | 'fr' | 'it'&#x22;,
    required: true,
    description: 'Language of the UI.',
  },
  api: {
    type: 'string',
    default: &#x22;'/api/helpdesk'&#x22;,
    description: 'Base URL of the handler.',
  },
  messages: {
    type: 'Record<string, string>',
    description: <>Overrides for the package's own strings by key, such as <code>{&#x22;{ 'admin.inbox': 'Queue' }&#x22;}</code>. Every key is listed on <a href=&#x22;/docs/customize/strings&#x22;>UI strings</a>.</>,
  },
  location: {
    type: '{ pathname: string; search: string }',
    description: &#x22;The host router's current location. With onNavigate, the host does the routing; without both, the UI uses the History API.&#x22;,
  },
  onNavigate: {
    type: '(href: string) => void',
    description: 'Called with the href to go to when the UI navigates.',
  },
  nav: {
    type: 'boolean',
    default: 'true',
    description: <>Shows the rail of section tabs, the notification bell and the away control. Off when the host renders its own tabs from <code>HELPDESK_SECTIONS</code>.</>,
  },
}"
/>

## Exports [#exports]

| Name                | Value                                                                                                                   |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `HelpdeskAdmin`     | The component.                                                                                                          |
| `HELPDESK_SECTIONS` | `['inbox', 'contacts', 'companies', 'deals', 'canned', 'overview', 'settings', 'audit']`                                |
| `HELPDESK_CHANGED`  | `'helpdesk:changed'`, an `Event` dispatched on `window` after each successful request the UI makes that is not a `GET`. |

## Sections and URLs [#sections-and-urls]

Each screen is a path under `basePath`; inbox filters are in the query string.

| Section     | Path                                                     | Shows                                                                                                                                                                                                                                                                                                                                                                                     |
| ----------- | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `inbox`     | `{basePath}/conversations/`                              | The conversation list, saved views, bulk actions, and **New conversation**, which opens one in the agent's name to a contact or an address.                                                                                                                                                                                                                                               |
|             | `{basePath}/conversations/{id}/`                         | One conversation beside the list.                                                                                                                                                                                                                                                                                                                                                         |
| `contacts`  | `{basePath}/contacts/` and `{basePath}/contacts/{id}/`   | Contacts, and one contact with its timeline.                                                                                                                                                                                                                                                                                                                                              |
| `companies` | `{basePath}/companies/` and `{basePath}/companies/{id}/` | Companies, and one company with its timeline.                                                                                                                                                                                                                                                                                                                                             |
| `deals`     | `{basePath}/deals/`                                      | The deals board.                                                                                                                                                                                                                                                                                                                                                                          |
| `canned`    | `{basePath}/canned/`                                     | Canned replies.                                                                                                                                                                                                                                                                                                                                                                           |
| `overview`  | `{basePath}/overview/`                                   | Statistics: volume, response and resolution times, ratings and tags, each figure a link into the inbox filtered to its conversations.                                                                                                                                                                                                                                                     |
| `settings`  | `{basePath}/settings/`                                   | The widget's confirmation text, one language tab at a time, [who gets emails about new requests](/docs/inbox/team#choose-who-gets-emails-about-new-requests), the [closed days](/docs/inbox/setup#close-on-holidays), what the [AI may do](/docs/ai/suggestions#choose-what-the-ai-does) when one is configured, the team with each member's role, and where an agent can remove another. |
| `audit`     | `{basePath}/audit/`                                      | The [audit log](/docs/inbox/team#roles) of every change made in the agent UI, 25 entries a page.                                                                                                                                                                                                                                                                                          |

A section that [`features`](/docs/reference/configuration#crm) switched off has no tab, and a link into it lands on the inbox. The same goes for `audit` when the agent may not read the log: once any agent has the `supervisor` role, only supervisors see it. A host that renders its own tabs from `HELPDESK_SECTIONS` can hide that tab by the `auditLog` field of [`GET agent/me`](/docs/reference/routes).

The inbox list reads `inbox`, `status`, `assignee`, `q`, `tag`, `tier`, `channel`, `sort`, `priority` and `days` from the query string. `status` is one of the statuses, `any`, `snoozed`, `rated-good` or `rated-bad`; `assignee` is `me`, `none` or an agent id; `sort` is empty for longest waiting, `priority`, or `sla` for the nearest deadline, which the tray offers once the config has [service levels](/docs/inbox/sla). A row shows its tier and how long until its deadline, or how far past it. `days` is `7`, `30` or `90`, the Statistics periods: it keeps conversations resolved in that time for `status=resolved`, rated in it for `rated-good` and `rated-bad`, and opened, resolved or rated in it otherwise, so each figure on Statistics opens the conversations it counts. The All, Assigned to me and Unassigned counts are of the list the other filters give. Changing a filter keeps the open conversation open.

The bar above the list is one line: the assignee tabs, the search with the High and urgent switch beside it, which keeps the two highest of your `priorities`, a Filters button and New conversation. Saved views are a second row of tabs under the bar, styled like the assignee tabs, each with its count. The button opens a tray with the status, inbox, assignee, tag, tier, channel and sort filters and the period, and a footer with the work-the-queue switch on the left and, on the right, Reset view once any filter is set, the link to save the current filters as a view, the default Open list included, and Rename and Delete for the active view. The tray opens only from the button; a filter set elsewhere, by a saved view or a tag on a row, shows as a count on it. The bulk bar under a selection also offers **Reply to all** and **Note on all**, one text written to each selected conversation, with the same formatting toolbar as a reply; a reply to all assigns each unassigned conversation to the agent. A `viewer` sees a line at the top saying they can change nothing: no checkboxes and no bulk bar, no New conversation button, and in a conversation the properties as text instead of controls and no composer. Beside an open conversation the search and High and urgent move into the tray too. On a wide screen the list and the thread each scroll inside their own pane, so opening another conversation never moves the page, the two panes fill the window below whatever your app shows above them, so the reply box stays in view, and the list keeps its width when the side panel opens or closes; on a narrow one a conversation opened from deep in the list scrolls into view by the least amount. Agent emails link to `{adminUrl}/conversations/{id}/`, which opens the agent UI when `adminUrl` is the URL that `basePath` is mounted at.

## Keyboard shortcuts [#keyboard-shortcuts]

`?` opens the list of shortcuts in the UI. Single-key shortcuts, `?` among them, do not fire while focus is in a text field, while a dialog is open, during IME composition, with Cmd, Ctrl or Alt held, or when they are switched off. Mod is Cmd on a Mac and Ctrl elsewhere.

| Keys                | Where                                | Does                                                                                                |
| ------------------- | ------------------------------------ | --------------------------------------------------------------------------------------------------- |
| `j`, `k`            | Inbox                                | Next or previous conversation                                                                       |
| `Enter`             | Inbox                                | Open the highlighted conversation, unless focus is on a button or link                              |
| `x`                 | Inbox                                | Select or unselect it                                                                               |
| `Shift` `x`         | Inbox                                | Select everything up to it                                                                          |
| `e`                 | Conversation                         | Resolve                                                                                             |
| `a`                 | Conversation                         | Assign to me                                                                                        |
| `r`                 | Conversation                         | Write a reply                                                                                       |
| `n`                 | Conversation                         | Write an internal note                                                                              |
| `s`                 | Conversation                         | Skip to the next conversation; only while working the queue                                         |
| `z`                 | Conversation                         | Snooze                                                                                              |
| Mod `Enter`         | Composer                             | Send                                                                                                |
| Mod `Shift` `Enter` | Composer                             | Send and resolve; also in the menu beside Send, with "Resolve without a reply", which needs no text |
| Mod `B`, `I`, `U`   | Composer                             | Bold, italic, underline                                                                             |
| Mod `K`             | Composer with the formatting toolbar | Link                                                                                                |
| `/`                 | Empty reply                          | Canned replies; the text after `/` filters them by title                                            |
| `↑`, `↓`, `Enter`   | Canned-reply or `@` mention list     | Move, insert                                                                                        |
| `Escape`            | Conversation                         | Focus its row in the list                                                                           |
| `?`                 | Everywhere                           | The list of shortcuts                                                                               |

## Preferences [#preferences]

Each agent's switches are kept in that browser's `localStorage`.

| Key                   | Default  | Switch                                                                    |
| --------------------- | -------- | ------------------------------------------------------------------------- |
| `helpdesk.keys`       | on       | Single-key shortcuts, turned off in the list of shortcuts                 |
| `helpdesk.queue`      | off      | Working the queue: after a reply, the next conversation in the list opens |
| `helpdesk.titleCount` | on       | New notifications counted in the tab title                                |
| `helpdesk.aside`      | by width | The conversation's side panel open or closed                              |

## CSS custom properties [#css-custom-properties]

The agent UI renders into the host page, not a shadow root, and inherits the host's font. It reads these properties from any ancestor.

| Property                  | Default                                   | Styles                                                    |
| ------------------------- | ----------------------------------------- | --------------------------------------------------------- |
| `--helpdesk-bg`           | `#ffffff`                                 | Background                                                |
| `--helpdesk-fg`           | `#0c2034`                                 | Text                                                      |
| `--helpdesk-muted`        | `#486581`                                 | Secondary text                                            |
| `--helpdesk-border`       | `#e6e9ef`                                 | Borders                                                   |
| `--helpdesk-subtle`       | `#f6f7f9`                                 | Quiet backgrounds                                         |
| `--helpdesk-accent`       | `#0c2034`                                 | Buttons, links, the selected tab                          |
| `--helpdesk-accent-hover` | `#243b53`                                 | Accent on hover                                           |
| `--helpdesk-accent-fg`    | `#f0f4f8`                                 | Text on the accent                                        |
| `--helpdesk-danger`       | `#cf1124`                                 | Errors                                                    |
| `--helpdesk-warning`      | `#b44d12`                                 | Warnings                                                  |
| `--helpdesk-focus`        | `#f55068`                                 | Focus ring                                                |
| `--helpdesk-radius`       | `10px`                                    | Corners; controls step down from it and dialogs step up   |
| `--helpdesk-header-bg`    | `#d9e2ec`                                 | Initials avatars other than agents', which use the accent |
| `--helpdesk-note-border`  | `#f0b429`                                 | Border of internal notes                                  |
| `--helpdesk-note`         | the note border mixed with the background | Background of internal notes                              |

The widget's own properties are on [Widget](/docs/widget/reference#css-custom-properties).
