# Carousel modality

## **What's a&#x20;*****Modality*****?**

A modality allows for information to be transmitted to a user that goes beyond a standard message. Images, audio, structured text, haptic signals, videos, and more can be modalities you may want to provide users during conversation.

In chat applications, carousels are useful for providing users with a selection of options enriched with media and text information:&#x20;

* Offer hotel room options in a booking conversation
* Show location options in a venue search conversation

Each option in a carousel is represented as a card, and with a Touchpoint conversation, you can configure a carousel for users to select between one of several cards. Each card in the carousel typically contains:

* An id (UUIDv4 is recommended)
* An image or visual&#x20;

<details>

<summary>Show me the code</summary>

* Example requires a schema and modality matching the guide.
* Notice in the HTML file below:
  * Line 27: The `CarouselExample` defined above&#x20;
  * Line 73: The `CarouselExample` set in the `customModalities` object
* Update the HTML file
  * Line 61: with your `applicationUrl`
  * Line 63: with your `nlx-api-key`

{% code lineNumbers="true" %}

```html
<head> 
  <style>
    body {
      background-color: #f8f9fa;
    }
  </style>
</head>
<body>
  <script defer src="https://unpkg.com/@nlxai/touchpoint-ui/lib/index.umd.js"></script>
  <script type="module">
    const contentLoaded = () => {
      if (document.readyState === "loading") {
        return new Promise((resolve) => {
          window.addEventListener("DOMContentLoaded", () => {
            resolve();
          });
        });
      } else {
        return Promise.resolve();
      }
    };

    await contentLoaded();
    
    const { html, create, React } = nlxai.touchpointUi;
    
    const CarouselExample = ({ data, conversationHandler }) => {
      const [selected, setSelected] = React.useState(null);
      const carousel = html`
        <Carousel>
          ${data.map((cardData, cardIndex) => html`
            <CustomCard
              key=${cardIndex}
              selected=${selected === cardIndex}
              onClick=${() => {
                setSelected(cardIndex);
                conversationHandler.sendChoice(cardData.id);
              }}
            >
              <CustomCardImageRow
                src=${cardData.imageUrl}
                alt="Alt Text"
              />
              <CustomCardRow
                left=${html`
                  <BaseText>${cardData.leftText}</BaseText>
                `}
                right=${html`
                  <BaseText>${cardData.rightText}</BaseText>
                `}
              />
            </CustomCard>`
        )}
      </Carousel>`;
      return carousel;
    };

    const touchpointOptions = {
      config: {
        applicationUrl:
          "https://bots.studio.nlx.ai/c/..", // YOUR APPLICATION URL
        headers: {
          "nlx-api-key": "QkeLasdf389793", // YOUR API KEY
        },
        languageCode: "en-US",
      },
      windowSize: "full",
      colorMode: "light",
      theme: {
        accent: "purple"
      },
      customModalities: { 
        ExampleCarouselModality: CarouselExample
      }
    };
    const touchpoint = await create(touchpointOptions);
  </script>
</body>
```

{% endcode %}

</details>

***

### Checklist

You'll complete the following to successfully launch your application with a carousel Touchpoint:

* [ ] Create data request
* [ ] Create modality
* [ ] Create flow
* [ ] Deploy
* [ ] Install

***

### Step 1: Create carousel data request

{% hint style="success" %}
Est. time to complete: \~5 minutes
{% endhint %}

For this guide, you may use the provided static schema or use your own when setting up a [Data request](/platform/nlx-platform-guide/integrations/types/data-requests.md):&#x20;

* Select *Resources* in workspace menu > Choose *Data requests* > *New data request* > Provide the name `ExampleCarouselDataRequest`
* Switch to *Static* implementation under the *Implementation* tab (or switch to *External* if using own schema)
* Copy and paste the full schema below into the *JSON Response* field
* Select the *Response* model tab > Choose *<> Auto-generate* option
* Click *Set response model* > Click *Save*

```json
[
  {
    "id": "c45a0eb6-f132-4365-bec2-7efacca39f8c",
    "imageUrl": "https://picsum.photos/200/300?random=1",
    "leftText": "Example Left Text",
    "rightText": "Example Right Text"
  },
  {
    "id": "623c9b3d-1e15-4352-9630-b895e0a0e70f",
    "imageUrl": "https://picsum.photos/200/300?random=2",
    "leftText": "Beispiel Linker Text",
    "rightText": "Beispiel Rechter Text"
  },
  {
    "id": "9bbab9a9-7008-4308-b305-82140bed928f",
    "imageUrl": "https://picsum.photos/200/300?random=3",
    "leftText": "Texto Izquierdo de Ejemplo",
    "rightText": "Texto Derecho de Ejemplo"
  }
]
```

This sample schema of listed objects represents three cards:

* *id*: UUID of the card within the carousel
* *imageUrl*: Uses [picsum](https://picsum.photos/) for a unique image
* *leftText*: Text to be rendered on the left portion of each card
* *rightText*: Text to be rendered on the right portion of each card

***

### Step 2: Create carousel *modality*

{% hint style="success" %}
Est. time to complete: \~5 minutes
{% endhint %}

NLX uses [*Modalities*](/platform/nlx-platform-guide/flows-and-building-blocks/modalities.md) to pass structured data over channels. Touchpoint uses modalities to indicate which component should be rendered when enabled within a node of a flow.

For this modality, you'll use the same schema from Step 1:

<figure><img src="/files/IZ5Xyd9AbFl4nMUWnXNQ" alt=""><figcaption><p>Modality with sample carousel schema</p></figcaption></figure>

* Select *Resources* in workspace menu > Choose *Modalities* > New modality > Provide the name `ExampleCarouselModality`
* Click *<> Auto-Generate* option
* Copy and paste the schema from Step 1 > Choose  *Set schema*
* Click *Save*

***

### Step 3: Create flow

{% hint style="success" %}
Est. time to complete: \~10 minutes
{% endhint %}

Next, you'll use the resources created in the previous steps within a simple conversation flow that presents options to a user via the carousel modality and repeats their selection back to them.

<figure><img src="/files/9sB9ri1TpxIFGfS9XMDb" alt=""><figcaption><p>Sample Touchpoint Carousel flow</p></figcaption></figure>

* Select *Resources* from workspace menu > Choose *Flows* > Click *New flow*
* Create a new flow named `ExampleCarouselFlow`
* Within the [flow's Canvas](/platform/nlx-platform-guide/flows-and-building-blocks/overview/canvas.md), open the *Settings* icon > Under the *Training phrases* tab, disable *Enable training* toggle
* Add and link a [*Basic* node](/platform/nlx-platform-guide/flows-and-building-blocks/overview/nodes.md#basic) to the *Start* node > Provide a message on the *Basic* node (try "Hello! Here is a carousel demo")
* Add and link a *Data request* node to your *Basic* node > Set the request to the `ExampleCarouselDataRequest` created in Step 1
* Add and link a [*User choice* node](/platform/nlx-platform-guide/flows-and-building-blocks/overview/nodes.md#user-choice) to the *Data request* node's *Success* edge. On the *User choice* node's side panel, configure the following:
  * *Resolve* dropdown: Select `ExampleCarouselDataRequest`
  * *Choose* field: Enter `UserCarouselChoice`
  * *Choice label* and *Choice ID* fields: Enter curly brace { and select `{id}` from the options
  * *+ Add message*: Enter "Select a card:"
  * Click *Add functionality* > Select *Modalities*
  * Toggle *Enable* for `ExampleCarouselModality`
    * Click the *Tt* on the right of the text field and swap to *(x) PlaceHolders*
    * Set the placeholder dropdown to `ExampleCarouselDataRequest`
* Add and link another *Basic* node from the *User choice* node's *Match* edge:
  * \+ Add message: Enter "You selected: {UserCarouselChoice.id} with {UserCarouselChoice.leftText}".

{% hint style="info" %}
Open the placeholder menu by typing { and selecting from the options.
{% endhint %}

***

### Step 4: Deploy

{% hint style="success" %}
Est. time to complete: \~2 minutes
{% endhint %}

To employ the conversation flow with your carousel, you'll need to create your conversational AI application.

* Select *Applications* from workspace menu > Choose *New application* > Select *Custom* > Enter the name `ExampleCarouselApplication`
* Under the *Functionality* section of your app's *Configuration* tab, attach the `ExampleCarouselFlow`&#x20;
  * Select *Default behavior* > Assign `ExampleCarouselFlow` to the Welcome default
* From the Delivery section > Select *API* channel > Enter the name `ExampleCarouselAPIChannel`&#x20;
  * *<> Auto-generate* an API key
  * Add the following to *Whitelisted domains*:
    * &#x20;`https://preview-html.playcode.io`&#x20;
    * &#x20;`https://playcode.io/html`
* Click *Update channel*

A build now constructs a package of your application with a snapshot of current state of flows, languages, and application setup. A deployment then pushes a successful build to the communication channels where your app is installed:

* Click deployment status in upper right > Select *Build and deploy*
  * Review *Validation check* for critical errors or detected UX issues in custom flows. Before each new build initiates, a validation check is run to provide a preview of potential errors that may cause failed builds. Detected issues are listed with descriptions and potential solutions
  * You may provide a *Description* of notable build edits as a changelog
  * Click *Create build*
* Click deployment status in upper right > Select *All builds* > Choose *Deploy* on successful build > Click *Create deployment*

***

### Step 5: Install

{% hint style="success" %}
Est. time to complete: \~5 minutes
{% endhint %}

Your Touchpoint [Component](https://developers.nlx.ai/touchpoint-components) will:

* Iterate and render a card for each object from the list set in `ExampleCarouselDataRequest`&#x20;
* Use the [conversationHandler](https://developers.nlx.ai/touchpoint-components#defining-your-component) to send the selection back to the NLX client
* Use the [React useState](https://react.dev/reference/react/useState) feature to highlight the user's choice

{% hint style="info" %}
You'll use the [CustomCards](https://developers.nlx.ai/touchpoint-CustomCards) and the [HTML](https://developers.nlx.ai/touchpoint-components#building-html-components-without-transpiling) feature of Touchpoint to build a simple example.&#x20;
{% endhint %}

#### Touchpoint Component Example Code

{% code lineNumbers="true" %}

```javascript
const CarouselExample = ({ data, conversationHandler }) => {
  const [selected, setSelected] = React.useState(null);
  const carousel = html`
    <Carousel>
      ${data.map((cardData, cardIndex) => html`
        <CustomCard
          key=${cardIndex}
          selected=${selected === cardIndex}
          onClick=${() => {
            setSelected(cardIndex);
            conversationHandler.sendChoice(cardData.id);
          }}
        >
          <CustomCardImageRow
            src=${cardData.imageUrl}
            alt="Alt Text"
          />
          <CustomCardRow
            left=${html`
              <BaseText>${cardData.leftText}</BaseText>
            `}
            right=${html`
              <BaseText>${cardData.rightText}</BaseText>
            `}
          />
        </CustomCard>`
    )}
  </Carousel>`;
  return carousel;
};
```

{% endcode %}

#### Try the example carousel live

Now you're ready to test your carousel live! This next step uses the service, PlayCode, to run the sample HTML.

* From your application's *Configuration* tab in NLX, click the API channel
* Select the *Setup instructions* tab in the modal > Save your *Application URL* and *API Key*
* Head to: <https://playcode.io/html>
* Copy the entire HTML file and paste into PlayCode's editor
* Notice in the HTML file below:
  * Line 27: The `CarouselExample` defined above&#x20;
  * Line 73: The `CarouselExample` set in the `customModalities` object
* Update the HTML file
  * Line 61: with your `applicationUrl`
  * Line 63: with your `nlx-api-key`
* Click the green Play button ▶&#x20;
  * Then select "Hard Restart" to start the demo
* Open Touchpoint and experience the rendered demo

{% code lineNumbers="true" %}

```html
<head> 
  <style>
    body {
      background-color: #f8f9fa;
    }
  </style>
</head>

<body>
  <script defer src="https://unpkg.com/@nlxai/touchpoint-ui/lib/index.umd.js"></script>
  <script type="module">
    const contentLoaded = () => {
      if (document.readyState === "loading") {
        return new Promise((resolve) => {
          window.addEventListener("DOMContentLoaded", () => {
            resolve();
          });
        });
      } else {
        return Promise.resolve();
      }
    };
    
    await contentLoaded();
    
    const { html, create, React } = nlxai.touchpointUi;
    const CarouselExample = ({ data, conversationHandler }) => {
      const [selected, setSelected] = React.useState(null);
      const carousel = html`
        <Carousel>
          ${data.map((cardData, cardIndex) => html`
            <CustomCard
              key=${cardIndex}
              selected=${selected === cardIndex}
              onClick=${() => {
                setSelected(cardIndex);
                conversationHandler.sendChoice(cardData.id);
              }}
            >
              <CustomCardImageRow
                src=${cardData.imageUrl}
                alt="Alt Text"
              />
              <CustomCardRow
                left=${html`
                  <BaseText>${cardData.leftText}</BaseText>
                `}
                right=${html`
                  <BaseText>${cardData.rightText}</BaseText>
                `}
              />
            </CustomCard>`
        )}
      </Carousel>`;
      return carousel;
    };

    const touchpointOptions = {
      config: {
        applicationUrl:
          "https://bots.studio.nlx.ai/c/..", // YOUR APPLICATION URL
        headers: {
          "nlx-api-key": "QkeLasdf389793", // YOUR API KEY
        },
        languageCode: "en-US",
      },
      windowSize: "full",
      colorMode: "light",
      theme: {
        accent: "purple"
      },
      customModalities: { 
        ExampleCarouselModality: CarouselExample
      }
    };
    const touchpoint = await create(touchpointOptions);
  </script>
</body>
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.nlx.ai/platform/nlx-platform-guide/flows-and-building-blocks/advanced/touchpoint-modalities/carousel-modality.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
