> For the complete documentation index, see [llms.txt](https://docs.borndigital.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.borndigital.ai/for-advanced-users/conversation-design-tips/implementing-chat-buttons.md).

# Implementing chat buttons

Offer the customer clickable choices in the chat: chat buttons on intents, dynamic buttons from a variable, and how clicks are routed.

Chat buttons offer the customer ready-made answers they can click instead of typing. They make choices fast and unambiguous – but a customer can still type, and a caller on the phone never clicks, so a flow with buttons always needs a way to handle typed text too.

There are two ways to show buttons in an [Answer node](/digital-agent/conversation-flow/nodes-explained/answer-node.md):

* **Chat button on an intent** – a fixed button for each intent. Best when the options are known in advance.
* **Dynamic buttons** – the buttons come from a variable. Best when the options depend on the conversation, for example the customer's orders.

## Chat button on an intent

1. Open the Answer node and its **Intents** tab.
2. In a **Keywords**, **AI** or **Training set** intent, turn on **Chat button**.
3. Enter the **Label** – the text of the button.
4. Set the intent's **Next** node.

The buttons are shown in the order of the intents in the node; drag the intents to change it. **Condition** intents cannot have a chat button.

<figure><img src="https://4261467870-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6iQTvxgRZRwPS1NgIGEb%2Fuploads%2Fgit-blob-7e76f10b662b3908e9ff91957e7ea85f2605ade3%2Ftutorial-step2-goodbye-intent.png?alt=media" alt="A Keywords intent GOODBYE with the keywords bye, goodbye and thank you, and Chat button turned on with the Label Goodbye"><figcaption><p>A chat button on a Keywords intent</p></figcaption></figure>

<figure><img src="https://4261467870-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6iQTvxgRZRwPS1NgIGEb%2Fuploads%2Fgit-blob-a42b7aa6eaefd08ede6f4e53153356981d00ffa2%2Fchat-buttons-in-bubble.png?alt=media" alt="The DA Bubble with the welcome message and the Goodbye chat button above the input field"><figcaption><p>The same button in the bubble</p></figcaption></figure>

### How a click is routed

A click sends the button's label as the customer's message. Studio adds a matching rule for every button automatically, so **you do not need to repeat the label as a keyword or a training sentence**:

1. Chat buttons are checked first – a message equal to a button label (ignoring upper and lower case) goes to that intent's **Next** node.
2. Then the **Keywords**, **Condition** and **AI** intents, in the order of the node.
3. Then the **Training set** intents.

A customer who types the exact label is routed the same way as one who clicks.

{% hint style="warning" %}
**Keep labels to plain words and numbers.** Characters such as `( ) ? + * . [ ] | ^ $ \` and quotation marks in a label break the automatic matching – a click on *Yes (recommended)* would not be recognised. Use *Yes, recommended* instead.
{% endhint %}

Good to know:

* A click goes straight to the intent's **Next** node. **Reuse utterance** does not apply to clicks.
* If the node has **AI** intents, the model is still asked to recognise the intent when a button is clicked – a click costs one model call.
* Variables such as `{name}` are not replaced in a static label. For labels that change, use dynamic buttons.

{% hint style="info" %}
The **Icon**, **Icon URL** and **Primary** / **Secondary** settings of a chat button are stored with the flow, but the current DA Bubble shows all buttons the same way.
{% endhint %}

## Dynamic buttons

Dynamic buttons are built from a variable that holds a **list of texts**, one per button.

### 1. Fill the variable

In a Function node before the Answer node, set a variable – for example `order_buttons`:

```python
["Track order", "Cancel order", "Talk to an agent"]
```

The list can also be built from data you already have:

* **From an API call** – for example the names of the customer's orders, at most five:

  ```python
  [o["name"] for o in api_result["orders"]][:5]
  ```
* **From an AI node** – set the AI node's response format to JSON and ask the model for `{"buttons": ["…", "…"]}`. Then, in a Function node:

  ```python
  json.loads(gpt_response["response_text"])["buttons"]
  ```

  The number of buttons simply follows the length of the list.

{% hint style="warning" %}
The variable must be a **list of texts**. A single text, a dictionary or an undefined variable shows no buttons. Remove empty items, for example with `[b for b in items if b]`.
{% endhint %}

### 2. Show the buttons

In the Answer node, click **Add intent** › **Dynamic buttons** and choose the **Variable**, for example `order_buttons`. A node can have one dynamic-buttons intent.

When dynamic buttons are set, the chat buttons of the other intents are **not shown**, and clicks are **not routed automatically**.

### 3. Route the clicks

A click sends the text of the button. Match it with intents:

* **One rule for all buttons** – a **Condition** intent `current_utterance in order_buttons`. In its **Variables**, store the choice, for example `chosen_order = current_utterance`, and continue to the node that handles it.
* **A specific button** – a **Keywords** intent with the keyword `^Talk to an agent$`, placed above the general condition.

## Buttons and typed text together

Buttons disappear as soon as the customer clicks one or sends a typed message. Plan for both:

* **Buttons plus free text** – keep Keywords, AI or Training set intents for typed answers. Button clicks are checked first, typed text falls through to the other intents.
* **Buttons only** – turn off **Chat input field** in the Answer node's **Configuration** › **Chat features**. The customer can then only click.
* **Always set a Fallback.** Typed text that matches nothing, and every phone call, end up there.
* **One click is one choice.** For several choices at once, use a [widget](/digital-agent/advanced-functions/widgets.md) with checkboxes.

## Ideas

* **A way out of an AI conversation** – an Answer node after the AI node with the buttons *Ask another question* and *Talk to an agent*, so the customer can leave the loop at any time.
* **Main menu** – three to five buttons with the most common topics, plus an AI intent for everything else.
* **Confirmation** – *Yes* / *No* buttons after the agent repeats what it understood.
