

# Add a chat user interface to your website hosted by Amazon Connect
<a name="add-chat-to-website"></a>

To support your customers through chat, you can add a communications widget to your website that is hosted by Amazon Connect. You can configure the communications widget in the Amazon Connect admin website. You can customize the font and colors, and secure the widget so that it can be launched only from your website. When finished, you will have a short code snippet that you add to your website. 

Because Amazon Connect hosts the widget, it ensures that the latest version is always live on your website. 

**Tip**  
Use of the communications widget is subject to default service quotas, such as the number of required characters for each message. Before launching your communications widget into production, make sure that your service quotas are set for your organization's needs. For more information, see [Amazon Connect service quotas](amazon-connect-service-limits.md). 

**Topics**
+ [Supported widget snippet fields that are customizable](supported-snippet-fields.md)
+ [Supported browsers](#chat-widget-supported-browsers)
+ [Step 1: Customize your communications widget](#customize-chat-widget)
+ [Step 2: Specify the website domains where you expect to display the communications widget](#chat-widget-domains)
+ [Step 3: Confirm and copy communications widget code and security keys](#confirm-and-copy-chat-widget-script)
+ [Getting error messages?](#chat-widget-error-messages)
+ [Customize widget launch behavior and button icon](customize-widget-launch.md)
+ [Pass the customer display name](pass-display-name-chat.md)
+ [Pass contact attributes](pass-contact-attributes-chat.md)
+ [Additional customizations for your chat widget](pass-customization-object.md)
+ [Download the transcript for your chat widget](chat-widget-download-transcript.md)
+ [Download and customize our open source example](download-chat-example.md)
+ [Start chats in your applications by using Amazon Connect APIs](integrate-with-startchatcontact-api.md)
+ [Send browser notifications to customers when chat messages arrive](browser-notifications-chat.md)
+ [Programmatic chat disconnect](programmatic-chat-disconnect.md)
+ [Pass custom properties to override the defaults in the communications widget](pass-custom-styles.md)
+ [Target your widget button and frame with CSS/JavaScript](target-widget-button.md)
+ [Troubleshoot issues with your communications widget](ts-cw.md)
+ [Add a pre-contact or pre-chat form](add-precontact-form.md)
+ [Post-chat survey](enable-post-chat-survey.md)

# Supported widget snippet fields in Amazon Connect that are customizable
<a name="supported-snippet-fields"></a>

The following table lists the communications widget snippet fields that you can customize. Example code after the table shows how to use the snippet fields.


| Snippet field | Type | Description | Additional documentation | 
| --- | --- | --- | --- | 
| `snippetId` | String | Mandatory, auto-generated | n/a | 
| `styles` | String | Mandatory, auto-generated | n/a | 
| `supportedMessagingContentTypes` | Array | Mandatory, auto-generated | n/a | 
| `customLaunchBehavior` | Object | Customize how your website renders and launches the hosted widget icon | [Customize widget launch behavior and button icon for your website hosted in Amazon Connect](customize-widget-launch.md), later in this topic | 
| `authenticate` | Function | Callback function to enable JWT security on your website | [Step 2: Specify the website domains where you expect to display the communications widget](add-chat-to-website.md#chat-widget-domains), earlier in this section. | 
| `customerDisplayName` | Function | Pass the customer display name when initializing a contact | [Pass the customer display name when an Amazon Connect chat starts](pass-display-name-chat.md), later in this section. | 
| `customStyles` | Object | Override the default CSS styles | [Pass custom properties to override the defaults in the communications widget in Amazon Connect](pass-custom-styles.md), later in this section. | 
| `chatDurationInMinutes` | Number | The total duration of the newly started chat session | Default: 1500 - Min 60, Max: 10080 | 
| `enableLogs` | Boolean | Enable the debugging logs | Default: false | 
| `language` | String |  Amazon Connect can do translations for supported ISO-639 format language codes. For more information, see [ https://en.wikipedia.org/wiki/List\$1of\$1ISO\$1639-1\$1codes](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). This would not translate custom text overrides and message content (both sent and received).  | Default: en\$1US. Supported: 'cs\$1CZ', 'da\$1DK', 'de\$1DE', 'en\$1AU', 'en\$1CA', 'en\$1GB', 'en\$1US', 'es\$1ES', 'fi\$1FI', 'fr\$1FR', 'hu\$1HU', 'id\$1ID', 'it\$1IT', 'ja\$1JP', 'ko\$1KR', 'nl\$1NL', 'nn\$1NO' 'pt\$1BR', 'pt\$1PT', 'sk\$1SK', 'sv\$1SE', 'zh\$1CN', 'zh\$1TW' | 
| `disableCSM` | Boolean | Disable tracking of the client-side metrics from the communication widget. | Default: false | 
| `nonce` | String | Handshake value between iframe and customer website csp policy. Example: customer csp allows 1234 nonce value, iframe which pulls in another script must have the same 1234 nonce value so that browser knows it is a trusted script by iframe parent site. | Default: undefined | 
| `customizationObject` | Object | Customize the widget layout and transcript | For more information, see [Additional customizations for your Amazon Connect chat widget](pass-customization-object.md), later in this section. | 
| `contactAttributes` | Object | Pass attributes to the contact flow directly from snippet code, without any JWT setup | For more information, see [ Pass contact attributes when a chat initializes](https://docs.aws.amazon.com/connect/latest/adminguide/pass-contact-attributes-chat.html). | 
| `customDisplayNames` | Object | Override the System or Bot display name and logo configurations set in the Amazon Connect admin website. | For more information, see [ How to pass override system and bot display names and logos for the communications widget ](https://docs.aws.amazon.com/connect/latest/adminguide/pass-custom-styles.html#pass-override-system). | 
| `contactMetadataHandler` | Function | Callback function to access contactId. For example, add an event listener to handle scenarios like calling the StopContact function with the contactId when the browser tab is closed or maintaining chat persistence with a previous contactId.  |  | 
| `registerCallback` | Object | This allows to execute callbacks for the exposed lifecycle events.  For more information, see [amazon-connect-chatjs](https://github.com/amazon-connect/amazon-connect-chatjs).  | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/connect/latest/adminguide/supported-snippet-fields.html) | 
| `initialMessage` | String | Message to be sent to the newly created chat. Length Constraints: Minimum of 1, Maximum of 1024. | To invoke the Lex bot configured in the contact flow using an initial message, modify the [Get customer input flow block](get-customer-input.md) by selecting the **Initialize bot with message** option. For more information, see [How to configure Get customer input flow block](get-customer-input.md#get-customer-input-properties). | 
| `authenticationParameters` | Object | This enables the [Authenticate Customer](authenticate-customer.md) flow block | For more information, see [Enable customer authentication](enable-connect-managed-auth.md). | 
| `mockLexBotTyping` | Boolean | Enable mocking typing indicator for Lex Bot messages. | Default: false | 
| `customStartChat` | Function | Callback function to call Start Chat API from your backend. | For more information, see [Hosted widget UI with custom Start Chat API](https://github.com/amazon-connect/amazon-connect-chat-interface#option-3-hosted-widget-ui-with-custom-start-chat-api)  | 

The following example shows how to add snippet fields to the HTML script that adds the chat widget to your web site.

```
(function(w, d, x, id) {   /* ... */})(window, document, 
'amazon_connect', 'widgetId');
 amazon_connect('snippetId', 'snippetId');
 amazon_connect('styles', /* ... */);
 amazon_connect('registerCallback', {
    // Custom event example
    // WIDGET_FRAME_CLOSED
    /**
     * This event is triggered when user clicks on the chat widget close button, 
     * either widget close button was clicked when error in the chat session or normally by the user. 
     * This event can be used for webview use cases to go back to main app
     * 
     * @param {string} status - The reason for widget closure
     *   - "error_chat": Indicates the user clicked on widget close button due to an error in the chat session
     *   - "close_chat": Indicates the user clicked on widget close button normally by the user
     */
    'WIDGET_FRAME_CLOSED': (eventName, { status }) => {
        // You can implement custom logic based on the status value(error_chat or close_chat)
        if (status == "error_chat") {
            // handle error chat
        } else if (status == "close_chat") {
            // handle close chat  
        } 
    },
    // System event example
    /**
     * chatDetails: { 
     *     contactId: string, 
     *     participantId: string,
     *     participantToken: string,
     * }
     * data: {
     *     AbsoluteTime?: string,
     *     ContentType?: string,
     *     Type?: string,
     *     ParticipantId?: string,
     *     DisplayName?: string,
     *     ParticipantRole?: string,
     *     InitialContactId?: string
     * }
     */
    'PARTICIPANT_JOINED': (eventName, { chatDetails, data }) => {
        alert(`${data.ParticipantRole} joined the chat.`);
    },
    'event_Name_3': callback(function),
    'event_Name_4': callback(function),
    // ...
}); 
amazon_connect('initialMessage', 'Your initial message string');
// ... 
amazon_connect('snippetFieldHere', /* ... */);
<script/>
```

## Supported browsers
<a name="chat-widget-supported-browsers"></a>

The pre-built communications widget supports the following browser versions and higher: 
+ Google Chrome 85.0
+ Safari 13.1
+ Microsoft Edge version 85
+ Mozilla Firefox 81.0

The communications widget supports browser notifications for desktop devices. For more information, see [Send browser notifications to customers when chat messages arrive](browser-notifications-chat.md).

## Step 1: Customize your communications widget
<a name="customize-chat-widget"></a>

In this step, you customize the experience of the communications widget for your customers.

1. Log in to the Amazon Connect admin website at https://*instance name*.my.connect.aws/. Choose **Customize communications widget**.  
![\[The configuration guide page, the customize communications widget link.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/chatwidget-customize-chat-window-button.png)

1. On the **Communications widgets** page, choose **Add communications widget** to begin customizing a new communications widget experience. To edit, delete, or duplicate an existing communications widget, choose from the options under the **Actions** column, as shown in the following image.   
![\[The communications widgets page, add communications widget button link.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/chatwidget-add-chat-widget.png)

1. Enter a **Name** and **Description** for the communications widget. 
**Note**  
The Name must be unique for each communications widget created in an Amazon Connect instance. 

1. In the **Communications options** section, choose how your customers can engage with your widget, and then choose **Save and continue**.
**Note**  
You can only enable a task or email pre-contact form if chat and voice are not enabled.

   The following image shows options to allow chat, message receipts, and create a pre-chat form for customers. To enable a pre chat form, you must first create a [view](view-resources-sg.md) with a connect action button and select the `StartChatContact` action. For more information about pre-chat and pre-contact forms, see [Add the Amazon Connect widget to your website](connect-widget-on-website.md).  
![\[The communication widget page configured for chat and web calling.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/comm-widget-page-chat.png)

1. On the **Create communication widget** page, choose the widget button styles, and display names and styles.

   As you choose these options, the widget preview updates automatically so that you can see what the experience will look like for your customers.  
![\[The preview of the communications widget.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/netra-chat-preview.png)

**Button styles**

1. Choose the colors for the button background by entering hex values ([HTML color codes](https://htmlcolorcodes.com/)).

1. Choose **White** or **Black** for the icon color. The icon color can't be customized.

**Widget header**

1. Provide values for header message and color, and widget background color. 

1. **Logo URL**: Insert a URL to your logo banner from an Amazon S3 bucket or another online source.
**Note**  
The communications widget preview in the customization page will not display the logo if it's from an online source other than an Amazon S3 bucket. However, the logo will be displayed when the customized communications widget is implemented to your page.

   The banner must be in .svg, .jpg or .png format. The image can be 280px (width) by 60px (height). Any image larger than those dimensions will be scaled to fit the 280x60 logo component space.

   1. For instructions about how to upload a file such as your logo banner to S3, see [Uploading objects](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html) in the *Amazon Simple Storage Service User Guide*.

   1. Make sure that the image permissions are properly set so that the communications widget has permissions to access the image. For information about how to make a S3 object publicly accessible, see [Step 2: Add a bucket policy](https://docs.aws.amazon.com/AmazonS3/latest/userguide/WebsiteAccessPermissionsReqd.html#bucket-policy-static-site) in the *Setting permissions for website access* topic.

**Chat view**

1.  **Typeface**: Use the dropdown to choose the font for the text in the communications widget.

1. 
   + **System Message Display Name**: Type a new display name to override the default. The default is **SYSTEM\$1MESSAGE**.
   + **Bot Message Display Name**: Type a new display name to override the default. The default is **BOT**.
   + **Text Input Placeholder**: Type new placeholder text override the default. The default is **Type a message**. 
   + **End Chat Button Text**: Type new text to replace the default. The default is **End chat**.

1. **Agent chat bubble color**: Choose the colors for the agent's message bubbles by entering hex values ([HTML color codes](https://htmlcolorcodes.com/)).

1. **Customer chat bubble color**: Choose the colors for the customer's message bubbles by entering hex values ([HTML color codes](https://htmlcolorcodes.com/)). 

1. Choose **Save and continue**.

## Step 2: Specify the website domains where you expect to display the communications widget
<a name="chat-widget-domains"></a>

1. Enter the website domains where you want to place the communications widget. Chat loads only on websites that you select in this step. 

   Choose **Add domain** to add up to 50 domains.  
![\[The add domain option.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/chatwidget-add-domain.png)

   Domain allowlist behavior:
   + Subdomains are automatically included. For example, if you allow example.com, all its subdomains (like sub.example.com) are also allowed.
   + Protocol http:// or https:// must exactly match your configuration. Specify the exact protocol when setting up allowed domains.
   + All URL paths are automatically allowed. For example, if example.com is allowed, all pages under it (such as example.com/cart or example.com/checkout) are accessible. You cannot allow or block specific subdirectories.
**Important**  
Double-check that your website URLs are valid and does not contain errors. Include the full URL starting with https://.
We recommend using https:// for your production websites and applications.

1. Under **Add security for your communications widget**, we recommend choosing **Yes**, and working with your website administrator to set up your web servers to issue JSON Web Tokens (JWTs) for new chat requests. This provides you more control when initiating new chats, including the ability to verify that chat requests sent to Amazon Connect are from authenticated users.  
![\[The activation of security for new communication widget requests.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/chatwidget-choose-security.png)

   Choosing **Yes** results in the following:
   + Amazon Connect provides a 44-character security key on the next page that you can use to create JSON Web Tokens (JWTs).
   + Amazon Connect adds a callback function within the communications widget embed script that checks for a JSON Web Token (JWT) when a chat is initiated.

     You must implement the callback function in the embedded snippet, as shown in the following example.

     ```
     amazon_connect('authenticate', function(callback) {
       window.fetch('/token').then(res => {
         res.json().then(data => {
           callback(data.data);
         });
       });
     });
     ```

   If you choose this option, in the next step you'll get a security key for all chat requests initiated on your websites. Ask your website administrator to set up your web servers to issue JWTs using this security key. 

1. Choose **Save**.

## Step 3: Confirm and copy communications widget code and security keys
<a name="confirm-and-copy-chat-widget-script"></a>

In this step, you confirm your selections and copy the code for the communications widget and embed it in your website. If you chose to use JWTs in [Step 2](#chat-widget-domains), you can also copy the secret keys for creating them. 

### Security key
<a name="chat-widget-security-key"></a>

Use this 44-character security key to generate JSON web tokens from your web server. You can also update, or rotate, keys if you need to change them. When you do this, Amazon Connect provides you with a new key and maintains the previous key until you have a chance to replace it. After you have the new key deployed, you can come back to Amazon Connect and delete the previous key.

![\[The security key provided by Amazon Connect.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/chatwidget-security-key.png)


When your customers interact with the Start chat icon on your website, the communications widget requests your web server for a JWT. When this JWT is provided, the widget will then include it as part of the end customer’s chat request to Amazon Connect. Amazon Connect then uses the secret key to decrypt the token. If successful, this confirms that the JWT was issued by your web server and Amazon Connect routes the chat request to your contact center agents.

#### JSON Web Token specifics
<a name="jwt"></a>
+ Algorithm: **HS256**
+ Claims:
  + **sub**: *widgetId*

    Replace `widgetId` with your own widgetId. To find your widgetId, see the example at [Communications widget script](#chat-widget-script).
  + **iat**: \$1Issued At Time.
  + **exp**: \$1Expiration (10 minute maximum).
  + **segmentAttributes (optional)**: A set of system defined key-value pairs stored on individual contact segments using an attribute map. For more information check SegmentAttributes in the [StartChatContact](https://docs.aws.amazon.com/connect/latest/APIReference/API_StartChatContact.html#connect-StartChatContact-request-SegmentAttributes) API.
  + **attributes (optional)**: Object with string-to-string key-value pairs. The contact attributes must follow the limitations set by the [StartChatContact](https://docs.aws.amazon.com/connect/latest/APIReference/API_StartChatContact.html#connect-StartChatContact-request-Attributes) API.
  + **relatedContactId (optional)**: String with valid contact id. The relatedContactId must follow limitations set by the [StartChatContact](https://docs.aws.amazon.com/connect/latest/APIReference/API_StartChatContact.html) API.
  + **customerId (optional)**: This can be either an Amazon Connect Customer Profiles ID or a custom identifier from an external system, such as a CRM. 

  \$1 For information about the date format, see the following Internet Engineering Task Force (IETF) document: [JSON Web Token (JWT)](https://tools.ietf.org/html/rfc7519), page 5. 

The following code snippet shows an example of how to generate a JWT in Python:

```
import jwt 
import datetime 
CONNECT_SECRET = "your-securely-stored-jwt-secret" 
WIDGET_ID = "widget-id" 
JWT_EXP_DELTA_SECONDS = 500

payload = { 
'sub': WIDGET_ID, 
'iat': datetime.datetime.utcnow(), 
'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=JWT_EXP_DELTA_SECONDS), 
'customerId': "your-customer-id",
'relatedContactId':'your-relatedContactId',                    
'segmentAttributes': {"connect:Subtype": {"ValueString" : "connect:Guide"}}, 'attributes': {"name": "Jane", "memberID": "123456789", "email": "Jane@example.com", "isPremiumUser": "true", "age": "45"} } 
header = { 'typ': "JWT", 'alg': 'HS256' } 
encoded_token = jwt.encode((payload), CONNECT_SECRET, algorithm="HS256", headers=header) // CONNECT_SECRET is the security key provided by Amazon Connect
```

### Communications widget script
<a name="chat-widget-script"></a>

The following image shows an example of the JavaScript that you embed on the websites where you want customers to chat with agents. This script displays the widget in the bottom-right corner of your website. 

![\[The communications widget script.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/chatwidget-code.png)


When your website loads, customers first see the **Start** icon. When they choose this icon, the communications widget opens and customers are able to send a message to your agents.

To make changes to the communications widget at any time, choose **Edit**.

**Note**  
Saved changes update the customer experience in a few minutes. Confirm your widget configuration before saving it. 

![\[he edit link on the widget preview.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/chatwidget-edit.png)


To make changes to widget icons on the website, you will receive a new code snippet to update your website directly.

## Getting error messages?
<a name="chat-widget-error-messages"></a>

If you encounter error messages, see [Troubleshoot issues with your Amazon Connect communications widget](ts-cw.md).

# Customize widget launch behavior and button icon for your website hosted in Amazon Connect
<a name="customize-widget-launch"></a>

To further customize how your website renders and launches the hosted widget icon, you can configure the launch behavior and hide the default icon. For example, you can programmatically launch the widget from a **Chat with us** button element that is rendered on your website.

**Topics**
+ [How to configure custom launch behavior for the widget](#config-widget-launch)
+ [Supported options and constraints](#launch-options-constraints)
+ [Configure widget launch for custom use cases](#launch-usage)
+ [Enable chat session persistence across tabs](#chat-persistence-across-tabs)

## How to configure custom launch behavior for the widget
<a name="config-widget-launch"></a>

To pass custom launch behavior, use the following example code block and embed it in your widget. All of the fields shown in the following example are optional and any combination can be used.

```
amazon_connect('customLaunchBehavior', {
    skipIconButtonAndAutoLaunch: true,
    alwaysHideWidgetButton: true,
    programmaticLaunch: (function(launchCallback) {
        var launchWidgetBtn = document.getElementById('launch-widget-btn');
        if (launchWidgetBtn) {
            launchWidgetBtn.addEventListener('click', launchCallback);
            window.onunload = function() {
            launchWidgetBtn.removeEventListener('click', launchCallback);
            return;
            }
        }
    })
});
```

## Supported options and constraints
<a name="launch-options-constraints"></a>

The following table lists the supported custom launch behavior options. Fields are optional and any combination can be used.


| Option name | Type | Description | Default value | 
| --- | --- | --- | --- | 
|  `skipIconButtonAndAutoLaunch`  | Boolean  | A flag to enable/disable the automatic launch of the widget without the user clicking on the page load. | undefined | 
|  `alwaysHideWidgetButton`  | Boolean  | A flag to enable/disable the widget icon button from rendering (unless there is an ongoing chat session). | undefined | 
|  `programmaticLaunch`  | Function  |  | undefined | 

## Configure widget launch for custom use cases
<a name="launch-usage"></a>

### Custom widget launch button
<a name="custom-launch-button"></a>

The following example shows changes you would need to make in the widget to configure programmatic launch to open only when the user chooses a custom button element rendered anywhere on your website. For example, they may choose a button named **Contact Us** or **Chat With Us**. Optionally, you can hide the default Amazon Connect widget icon until the widget has been opened.

```
<button id="launch-widget-btn">Chat With Us</button>
```

```
<script type="text/javascript">
 (function(w, d, x, id){
    s=d.createElement("script");
    s.src="./amazon-connect-chat-interface-client.js"
    s.async=1;
    s.id=id;
    d.getElementsByTagName("head")[0].appendChild(s);
    w[x] =  w[x] || function() { (w[x].ac = w[x].ac || []).push(arguments) };
  })(window, document, 'amazon_connect', 'asfd-asdf-asfd-asdf-asdf');
  amazon_connect('styles', { openChat: { color: '#000', backgroundColor: '#3498fe'}, closeChat: { color: '#fff', backgroundColor: '#123456'} });
  amazon_connect('snippetId', "QVFJREFsdafsdfsadfsdafasdfasdfsdafasdfz0=")
  amazon_connect('customLaunchBehavior', {
        skipIconButtonAndAutoLaunch: true,
        alwaysHideWidgetButton: true,
        programmaticLaunch: (function(launchCallback) {
            var launchWidgetBtn = document.getElementById('launch-widget-btn');
            if (launchWidgetBtn) {
                launchWidgetBtn.addEventListener('click', launchCallback);
                window.onunload = function() {
                launchWidgetBtn.removeEventListener('click', launchCallback);
                return;
                }
            }
        }),
    });
</script>
```

### Hyperlink support
<a name="hyperlink-support"></a>

The following example shows changes you would need to make in the widget configure `auto-launch`, which opens the widget without waiting for the user to click. You can deploy to a page that hosted by your website to create a shareable hyperlink.

```
https://example.com/contact-us?autoLaunchMyWidget=true
```

```
<script type="text/javascript">
 (function(w, d, x, id){
    s=d.createElement("script");
    s.src="./amazon-connect-chat-interface-client.js"
    s.async=1;
    s.id=id;
    d.getElementsByTagName("head")[0].appendChild(s);
    w[x] =  w[x] || function() { (w[x].ac = w[x].ac || []).push(arguments) };
  })(window, document, 'amazon_connect', 'asfd-asdf-asfd-asdf-asdf');
  amazon_connect('styles', { openChat: { color: '#000', backgroundColor: '#3498fe'}, closeChat: { color: '#fff', backgroundColor: '#123456'} });
  amazon_connect('snippetId', "QVFJREFsdafsdfsadfsdafasdfasdfsdafasdfz0=")
  amazon_connect('customLaunchBehavior', {
        skipIconButtonAndAutoLaunch: true
    });
</script>
```

### Load widget assets when button is clicked
<a name="load-assets"></a>

The following example shows changes you would need to make in the widget to make your website page load faster by fetching the widget's static assets when a user clicks the **Chat With Us** button. Typically, only small percentage of customers visiting a **Contact Us** page open the Amazon Connect widget. The widget could be adding latency on page load by fetching files from CDN, even though customers never open the widget.

An alternative solution is to run the snippet code asynchronously (or never) on button click. 

```
<button id="launch-widget-btn">Chat With Us</button>
```

```
var buttonElem = document.getElementById('launch-widget-btn');

buttonElem.addEventListener('click', function() {
    (function(w, d, x, id){
        s=d.createElement("script");
        s.src="./amazon-connect-chat-interface-client.js"
        s.async=1;
        s.id=id;
        d.getElementsByTagName("head")[0].appendChild(s);
        w[x] =  w[x] || function() { (w[x].ac = w[x].ac || []).push(arguments) };
    })(window, document, 'amazon_connect', 'asfd-asdf-asfd-asdf-asdf');
    amazon_connect('styles', { openChat: { color: '#000', backgroundColor: '#3498fe'}, closeChat: { color: '#fff', backgroundColor: '#123456'} });
    amazon_connect('snippetId', "QVFJREFsdafsdfsadfsdafasdfasdfsdafasdfz0=")
    amazon_connect('customLaunchBehavior', {
        skipIconButtonAndAutoLaunch: true
    });
});
```

### Launch a new chat in a browser window
<a name="new-chat-browser-window"></a>

The following example shows changes you would need to make in the widget to launch a new browser window and auto-launch chat in a full screen.

```
<button id="openChatWindowButton">Launch a Chat</button>
```

```
<script> // Function to open a new browser window with specified URL and dimensions
    function openNewWindow() {
        var url = 'https://mycompany.com/support?autoLaunchChat=true';

        // Define the width and height
        var width = 300;
        var height = 540;

        // Calculate the left and top position to center the window
        var left = (window.innerWidth - width) / 2;
        var top = (window.innerHeight - height) / 2;

        // Open the new window with the specified URL, dimensions, and position
        var newWindow = window.open(url, '', 'width=${width}, height=${height}, left=${left}, top=${top}');
    }

    // Attach a click event listener to the button
    document.getElementById('openChatWindowButton').addEventListener('click', openNewWindow);
</script>
```

## Enable chat session persistence across tabs
<a name="chat-persistence-across-tabs"></a>

By default if a chat is opened in one tab and then the user opens a new tab and starts another chat, a new chat will start instead of connecting to the existing chat. You can enable chat session persistence across tabs if you want the user to connect to the existing chat that was started in the initial tab. 

The chat session is stored in session storage on the browser in the variable `persistedChatSession`. You need to copy this value into the session storage of the new tab when the widget is first initialized. Following are instructions.

To connect to the same chat session when user navigates to different subdomains, you can set the domain property of the cookie. For example, you own two subdomains: `domain1.example.com` and `domain2.example.com`. You can add the property `domain=.example.com` so that the cookie can be accessed from all subdomains.

1. Copy the following code next to the other amazon\$1connect functions in the hosted widget snippet. This uses the `registerCallback` event handlers to store the `persistedChatSession` as a cookie so it can be accessed in the new tab. It also cleans up the cookie when the chat ends.

   

   ```
   amazon_connect('registerCallback', {
   'CONNECTION_ESTABLISHED': (eventName, { chatDetails, data }) => {
    document.cookie = `activeChat=${sessionStorage.getItem("persistedChatSession")}; SameSite=None; Secure`;
   }, 
   'CHAT_ENDED': () => {
     document.cookie = "activeChat=; SameSite=None; Secure";
   }
   });
   ```

1. Retrieve the cookie value if it exists and set the session storage value in the new tab.

   ```
   const cookie = document.cookie.split('; ').find(c => c.startsWith('activeChat='));
   if (cookie) {
     const activeChatValue = cookie.split('=')[1];
     sessionStorage.setItem('persistedChatSession', activeChatValue);
   }
   
   //Your hosted widget snippet should be on this page
   ```

# Pass the customer display name when an Amazon Connect chat starts
<a name="pass-display-name-chat"></a>

To deliver a more personalized experience for both your customers and agents, you can customize the Amazon Connect communications widget to pass the customer display name during contact initialization. The name is visible to both the customer and agent throughout the chat interaction. This display name is recorded in the chat transcript.

The following images show the customer's display name in their chat experience, and their name in the agent's CCP.

![\[The customer's name in their chat experience, the customer's name in the agent's CCP.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/chatwidget-displayname.png)


1. How the customer display name may appear to the customer using the chat user interface.

1. How the customer display name may appear to the agent using the CCP.

## How to pass a customer display name in the communications widget
<a name="setup-display-name"></a>

To pass a customer display name, implement your callback function in the snippet. Amazon Connect retrieves the display name automatically.

1. Complete the steps in [Add a chat user interface to your website hosted by Amazon Connect](add-chat-to-website.md), if you haven't already.

1. Augment your existing widget snippet to add a `customerDisplayName` callback. It might look something like the following example:

   ```
   amazon_connect('customerDisplayName', function(callback) {
     const displayName = 'Jane Doe';
     callback(displayName);
   });
   ```

   The important thing is that the name is passed to `callback(name)`.

## What you need to know about the customer display name
<a name="setup-display-name-important-notes"></a>
+ Only one `customerDisplayName` function can exist at a time.
+ The customer display name must follow the limitations set by the [StartChatContact](https://docs.aws.amazon.com/connect/latest/APIReference/API_StartChatContact.html#connect-Type-ParticipantDetails-DisplayName) API. That is, the name must be a string between 1 and 256 characters.
+ An empty string, null, or undefined is invalid input for the display name. To protect against accidentally passing of these inputs, the widget logs an error, `Invalid customerDisplayName provided`, in the browser console, and then starts the chat with the default display name, **Customer**.
+ Because the snippet is in the front end of your website, do not pass sensitive data as the display name. Be sure to follow the appropriate security practices to keep your data safe and protect against attacks and bad actors.

# Pass contact attributes to an agent in the Contact Control Panel (CCP) when a chat starts
<a name="pass-contact-attributes-chat"></a>

You can use [contact attributes](what-is-a-contact-attribute.md) to capture information about the contact who is using the communications widget. Then, you can display that information to the agent through the Contact Control Panel (CCP), or use it elsewhere in the flow.

For example, you can customize your flow to say the name of the customer in your welcome message. Or, you can use attributes specific to your business, such as account/member IDs, customer identifiers like names and emails, or other metadata associated with a contact.

## How to pass contact attributes into the communications widget
<a name="how-to-contact-attributes-chatwidget"></a>

1. Enable security in the communications widget as described in [Add a chat user interface to your website hosted by Amazon Connect](add-chat-to-website.md), if you haven't already:

   1. In Step 2, under **Add security for your chat widget**, choose **Yes**.

   1. In Step 3, use the security key to generate JSON web tokens.

1. Add the contact attributes to the payload of your JWT as an `attributes` claim.

   Following is an example of how you might generate a JWT with contact attributes in Python:
**Note**  
JWT should be installed as a prerequisite. To install it, run `pip install PyJWT` in your terminal.

   ```
   import jwt 
   import datetime 
   CONNECT_SECRET = "your-securely-stored-jwt-secret" 
   WIDGET_ID = "widget-id" 
   JWT_EXP_DELTA_SECONDS = 500
   
   payload = { 
   'sub': WIDGET_ID, 
   'iat': datetime.datetime.utcnow(), 
   'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=JWT_EXP_DELTA_SECONDS), 
   'segmentAttributes': {"connect:Subtype": {"ValueString" : "connect:Guide"}}, 'attributes': {"name": "Jane", "memberID": "123456789", "email": "Jane@example.com", "isPremiumUser": "true", "age": "45"} } 
   header = { 'typ': "JWT", 'alg': 'HS256' } 
   encoded_token = jwt.encode((payload), CONNECT_SECRET, algorithm="HS256", headers=header) // CONNECT_SECRET is the security key provided by Amazon Connect
   ```

   In the payload, you must create a string key `attributes` (as-is, all lowercase), with an object as its value. That object must have string-to-string key-value pairs. If anything other than a string is passed in any one of the attributes, the chat will fail to start. 

   The contact attributes must follow the limitations set by the [StartChatContact](https://docs.aws.amazon.com/connect/latest/APIReference/API_StartChatContact.html#connect-StartChatContact-request-Attributes) API: 
   + Keys must have a minimum length of 1
   + Values can have a minimum length of 0

Optionally, you can add the segmentAttributes string to [SegmentAttributeValue](https://docs.aws.amazon.com/connect/latest/APIReference/API_SegmentAttributeValue.html) object map, in the payload. The attributes are standard Amazon Connect attributes. They can be accessed in flows. The contact attributes must follow the limitations set by the [StartChatContact](https://docs.aws.amazon.com/connect/latest/APIReference/API_StartChatContact.html#connect-StartChatContact-request-SegmentAttributes) API.

## Alternative method: Pass contact attributes directly from snippet code
<a name="pass-attributes-directly"></a>

**Note**  
The snippet code prepends `HostedWidget-` to all the contact attribute keys that it passes. In the following example, the agent side will see the key value pair `HostedWidget-foo: 'bar'`.
Although these attributes are scoped with the `HostedWidget-` prefix, they are still mutable client-site. Use the JWT setup if you require PII or immutable data in your flow. 

The following example shows how to pass contact attributes directly from snippet code without enabling widget security. 

```
<script type="text/javascript">
  (function(w, d, x, id){ /* ... */ })(window, document, 'amazon_connect', 'widgetId');
  amazon_connect('snippetId', 'snippetId');
  amazon_connect('styles', /* ... */);
  // ...

  amazon_connect('contactAttributes', {
   foo: 'bar'
  })
<script/>
```

### Using the attributes in flows
<a name="contact-flow-usage-chat"></a>

The [Check contact attributes](check-contact-attributes.md) flow block provides access to these attributes by using the **User defined** namespace, as shown in the following image. You can use the flow block to add branching logic. The full path is `$.Attributes.HostedWidget-attributeName`.

![\[Image showing a flow block branching to Valid and Invalid prompts.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/flow-check-contact-attrib.png)


## Things you need to know
<a name="contact-attributes-chatwidget-important-notes"></a>
+ The communications widget has a 6144 bytes limit for the entire encoded token. Because JavaScript uses UTF-16 encoding, 2 bytes are used per character, so the maximum size of the `encoded_token` should be around 3000 characters.
+ The encoded\$1token should be passed in to `callback(data)`. The `authenticate` snippet does not need any additional changes. For example:

  ```
  amazon_connect('authenticate', function(callback) {
    window.fetch('/token').then(res => {
      res.json().then(data => {
        callback(data.data);
      });
    });
  });
  ```
+ Using a JWT to pass contact attributes ensures the integrity of the data. If you safeguard the shared secret and follow appropriate security practices, you can help ensure that the data cannot be manipulated by a bad actor.
+ Contact attributes are only encoded in the JWT, not encrypted, so it's possible to decode and read the attributes.
+ If you want to test the chat experience with the [simulated chat experience](chat-testing.md#test-chat) and include contact attributes, be sure to enclose both the key and value in quotes, as shown in the following image.  
![\[The test settings page, a contact attribute key in quotes, a value in quotes.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/test-chat-contact-attributes.png)

# Additional customizations for your Amazon Connect chat widget
<a name="pass-customization-object"></a>

You can add the following optional customizations to your chat user interface:
+ Display the **End chat** button in the header dropdown menu instead of in the footer.
+ Mask or hide display names.
+ Add message icons.
+ Override event messages.
+ Configure a confirmation dialog that will be presented to customers when they choose the **End chat** button. This dialog verifies that customers intend to actually end the chat session. You can customize the confirmation dialog, title, message, and button text.
+ Override the attachment rejection message.
+ Display a **Minimize** button in the chat header.

## Configure the customization object
<a name="configure-customization-object"></a>

This example shows how to implement some of the optional customizations. For a list of all possible customizations, see [Supported options and constraints](#customization-options-constraints). Because these customizations are optional, you can implement some or all of the fields shown in the following example. Replace the `eventNames.customer`, `eventNames.agent`, `eventNames.supervisor`, `eventMessages.participantJoined`, `eventMessages.participantDisconnect`, `eventMessages.participantLeft`, `eventMessages.participantIdle`, `eventMessages.participantReturned`, and `eventMessages.chatEnded` strings as needed. Icons must be hosted on public URLs.

```
amazon_connect('customizationObject', {
        header: { 
            dropdown: true, 
            dynamicHeader: true,
            minimizeChatHeaderButton: true,
        },
        transcript: { 
            hideDisplayNames: false, 
            eventNames: {
                customer: "User",
                agent: "Webchat Agent",
                supervisor: "Webchat Supervisor"
            },
            eventMessages: {
                participantJoined: "{name} has joined the chat",
                participantDisconnect: "",
                participantLeft: "{name} has dropped",
                participantIdle: "{name}, are you still there?",
                participantReturned: "",
                chatEnded: "Chat ended",
            },
            displayIcons: true,
            iconSources: { 
                botMessage: "imageURL",
                systemMessage: "imageURL",
                agentMessage: "imageURL",
                customerMessage: "imageURL",
            },
        },
        composer: {
            disableEmojiPicker: true,
            disableCustomerAttachments: true,
            alwaysHideToolbar: true,
            hide: false,
        },
        footer: {
            disabled:true,
            skipCloseChatButton: true,
        },
        endChat: {
            enableConfirmationDialog: true,
            confirmationDialogText: {
                title: "End Chat",
                message: "Are you sure you want to end this chat?",
                confirmButtonText: "End Chat",
                cancelButtonText: "Cancel",
        },
    },
    attachment: {
         // Default rejectedErrorMessage: Attachment was rejected.
        rejectedErrorMessage: "Custom Error Message: Files cannot exceed 15 MB." //this is customizable attribute 
    }
});
```

The following image shows how the customizations look if you use the example:

![\[Diagram showing the customizable display names, menu locations, icons, and End chat confirmation dialog.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/chat-customization-diagram2.png)


## Supported options and constraints
<a name="customization-options-constraints"></a>

The following table lists the supported customization fields and recommended value constraints.


| Custom layout option | Type | Description | 
| --- | --- | --- | 
|  `header.dropdown`  |  Boolean  |  Renders the header dropdown menu instead of the default footer  When you set this option to `true`, the **Transcript download** button appears and remains visible until you set the option to `false`, or until you remove the option.   | 
| `header.dynamicHeader` | Boolean | Dynamically sets the header title to "Chatting with Bot/AgentName". | 
| `header.hideTranscriptDownloadButton` | Boolean | Hide the [download transcript](chat-widget-download-transcript.md) button in the header dropdown menu. The default value is false. | 
| `header.minimizeChatHeaderButton` | Boolean | Displays a Minimize button in the chat header. The default value is false. | 
|  `transcript.hideDisplayNames`  |  Boolean  |  Hides all display names, will apply default name masks if `eventNames` is not provided.  | 
|  `transcript.eventNames.customer`  |  String  |  Masks the display name of customer.  | 
|  `transcript.eventNames.agent`  |  String  |  Masks the display name of agent.  | 
|  `transcript.eventNames.supervisor`  |  String  |  Masks the display name of supervisor.  | 
|  ` transcript.eventMessages.participantJoined`  |  String  |  Overrides event message in the transcript for when a participant has joined the chat. If an empty string is specified, the event message will be omitted from the transcript. `{name}` can be passed in the message, and will be replaced with the display name of the corresponding participant. The default message is `{name} has joined the chat`.   | 
|  `transcript.eventMessages.participantDisconnect`  |  String  |  Overrides event message in the transcript for when a participant is disconnected from the chat. If an empty string is specified, the event message will be omitted from the transcript. `{name}` can be passed in the message, and will be replaced with the display name of the corresponding participant. The default message is \$1`name} has been idle too long, disconnecting`.  | 
|  `transcript.eventMessages.participantLeft`  |  String  |  Overrides event message in the transcript for when a participant has left the chat. If an empty string is specified, the event message will be omitted from the transcript. `{name}` can be passed in the message, and will be replaced with the display name of the corresponding participant. The default message is `{name} has left the chat`.  | 
|  `transcript.eventMessages.participantIdle`  |  String  |  Overrides event message in the transcript for when a participant is idle. If an empty string is specified, the event message will be omitted from the transcript. `{name}` can be passed in the message, and will be replaced with the display name of the corresponding participant. The default message is `{name} has become idle`.  | 
|  `transcript.eventMessages.participantReturned`  |  String  |  Overrides event message in the transcript for when a participant has returned to the chat. If an empty string is specified, the event message will be omitted from the transcript. `{name} `can be passed in the message, and will be replaced with the display name of the corresponding participant. The default message is `{name} has returned`.  | 
|  `transcript.eventMessages.chatEnded`  |  String  |  Overrides event message in the transcript for when the chat has ended. If an empty string is specified, the event message will be omitted from the transcript. `{name}` can be passed in the message, and will be replaced with the display name of the corresponding participant. The default message is `Chat has ended!`  | 
|  `transcript.displayIcons`  |  Boolean  |  Enables message display icons.  | 
|  `transcript.iconSources.botMessage`  |  String  |  Icon displayed for bot messages, must be hosted on a public URL.  | 
|  `transcript.iconSources.systemMessage`  |  String  |  Icon displayed for system message, must be hosted on a public URL.  | 
|  `transcript.iconSources.agentMessage`  |  String  |  Icon displayed for agent message, must be hosted on a public URL.  | 
|  `transcript.iconSources.customerMessage`  |  String  |  Icon displayed for customer message, must be hosted on a public URL.  | 
|  `composer.alwaysHideToolbar`  |  Boolean  |  Hides the formatting toolbar that includes text styling features such as Bold, Italic, and both bulleted and numbered list options.  | 
|  `composer.disableEmojiPicker`  |  Boolean  |  Disables the emoji picker when using the [rich text editor.](enable-text-formatting-chat.md)  | 
| `composer.disableCustomerAttachments` | Boolean | Prevents customers from sending or uploading attachments. | 
| `composer.hide` | Boolean | Hides the composer (`true`) or shows it (`false`). To toggle the composer based on events (such as when an agent joins), use `registerCallback` with the `hideComposer` method. For more information, see [Supported widget snippet fields in Amazon Connect that are customizable](supported-snippet-fields.md).<pre>document.getElementById("amazon-connect-chat-widget-iframe").contentWindow.connect.ChatInterface.hideComposer(false)</pre> | 
|  `footer.disabled`  |  Boolean  |  Hides the default footer and **End chat** button.  | 
|  `footer.skipCloseChatButton`  |  Boolean  |  Directly closes the widget on click of the **End chat** button instead of showing **Close** button.  | 
| `endChat.enableConfirmationDialog` | Boolean | Enables the End Chat confirmation dialog. Default texts are used if confirmationDialogText is not provided. | 
| `endChat.confirmationDialogText.title` | String | Overrides the title of End Chat confirmation dialog. | 
| `endChat.confirmationDialogText.message` | String | Overrides the message of End Chat confirmation dialog. | 
| `endChat.confirmationDialogText.confirmButtonText` | String | Overrides the confirm button text in End Chat confirmation dialog. | 
| `endChat.confirmationDialogText.cancelButtonText` | String | Overrides the cancel button text in End Chat confirmation dialog. | 
| `attachment.rejectedErrorMessage` | String | Overrides the error message for chat widget attachment rejection. | 

# Download the transcript for your chat widget in Amazon Connect
<a name="chat-widget-download-transcript"></a>

You can download a PDF of the transcript in your chat widget.

**Topics**
+ [Enable Header Dropdown](#chat-widget-download-transcript-enable-header-dropdown)
+ [Download PDF of Chat Transcript](#chat-widget-download-transcript-pdf)

## Enable Header Dropdown
<a name="chat-widget-download-transcript-enable-header-dropdown"></a>

The button to download the transcript is within a drop down menu in the header. To enable the header’s drop down menu, we have to configure our chat widget’s [customizationObject](pass-customization-object.md) in the widget script.

```
amazon_connect('customizationObject', {
        header: { 
            dropdown: true, 
        }
});
```

Note that enabling the drop down menu will automatically disable the footer since the **End Chat** functionality is moved to the header drop down menu. If you want to keep the footer, you can re-enable it by using the following:

```
amazon_connect('customizationObject', {
        header: { 
            dropdown: true, 
        },
        footer: {
            disabled: false,
        }
});
```

## Download PDF of Chat Transcript
<a name="chat-widget-download-transcript-pdf"></a>

After enabling the header drop down menu, you should be able to see a triple dot menu on the top left of the chat widget. Within that drop down menu, you should see a download **Chat Transcript** button.

![\[Shows button to download chat transcript.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/chat-widget-download-transcript-pdf-1.png)


Choosing download **Chat Transcript** will start a PDF download. The PDF of the chat transcript will show all messages, display names, time stamps and message events, such as participants leaving or joining.

![\[Downloaded chat transcript example.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/chat-widget-download-transcript-pdf-2.png)


# Customize chat with the Amazon Connect open source example
<a name="download-chat-example"></a>

You can further customize the chat experience customers use to interact with agents. Use the [Amazon Connect open source library](https://github.com/amazon-connect/amazon-connect-chat-ui-examples/tree/master/cloudformationTemplates/asyncCustomerChatUX) on GitHub. It's a platform to help you get started quickly. Here's how it works:
+ The GitHub repository links to a CloudFormation template, which starts the Amazon API Gateway endpoint that initiates a Lambda function. You can use this template as an example.
+ After you create the AWS CloudFormation stack, you can call this API from your app, import the pre-built communications widget, pass the response to the widget, and start chatting. 

For more information about customizing the chat experience, see: 
+ [Amazon Connect Service API Documentation](https://docs.aws.amazon.com/connect/latest/APIReference/welcome.html), especially the [StartChatContact](https://docs.aws.amazon.com/connect/latest/APIReference/API_StartChatContact.html) API. 
+  [Amazon Connect Participant Service API](https://docs.aws.amazon.com/connect-participant/latest/APIReference/Welcome.html). 
+  [Amazon Connect Streams](https://github.com/aws/amazon-connect-streams). Use to integrate your existing apps with Amazon Connect. You can embed the Contact Control Panel (CCP) components into your app. 
+ [Amazon Connect Chat SDK and Sample Implementations](https://github.com/amazon-connect/amazon-connect-chat-ui-examples/) 

# Start chats in your applications by using Amazon Connect APIs
<a name="integrate-with-startchatcontact-api"></a>

Use the StartChatContact API in Amazon Connect APIs to start chats in your own applications.

To start a chat, use the [StartChatContact](https://docs.aws.amazon.com/connect/latest/APIReference/API_StartChatContact.html) API.

When you explore the chat experience for the first time, you'll notice that chats aren't counted in the **Contacts Incoming** metric in your historical metrics report. This is because the initiation method for the chat in the contact record is **API**. 

The following image of a contact record shows the *Initiation Method* set to *API*. 

![\[A contact record, the initiation method set to API.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/ctr-api.png)


After a chat is transferred to an agent, the **Contacts Incoming** metric is incremented. The contact record for the transfer no longer increments the API, but it does increment **Contacts Incoming**. 

# Send browser notifications to customers when chat messages arrive
<a name="browser-notifications-chat"></a>

The communications widget supports browser notifications for your customers through their desktop devices. Specifically, your customers will receive a notification through their web browser when they receive a new message, but are not active on the web page that contains the chat window. When your customers click or tap this notification, they are automatically redirected to the web page containing the chat window. Your customers can enable or disable notifications at the start of each chat conversation. 

The following image shows an example of the notification banner that customers receive when they are not on the web page that contains the chat window. The banner tells your customers that they have a new message, and it displays the name of the website. 

![\[A Google Chrome banner that says you have received a new message.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/chatwidget-notification-banner.png)


Customers also receive a notification icon—a red dot—on the communications widget when it is minimized. The following image shows an image of the notification icon that customers receive when their chat window is minimized.

![\[A notification icon.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/chatwidget-browser-notification.png)


Both of these features are automatically included in the communications widget. You don't need to perform any steps to make them available to your customers.

Your customers receive a pop-up to allow/deny notification when they initiate a chat and have not yet allowed notifications from your website or domain. After they grant notification permissions, they start receiving browser notifications for any message or attachment sent by the agent when they are not on the web page with the chat window. This behavior applies even if you've already implemented the communications widget.

## How to test
<a name="test-browser-notifications-chat"></a>

1. After you allow notifications as a test customer and the agent is connected to the chat, minimize your chat window and then open a new browser instance so you aren't on the web page that contains the chat window.

1. Send a message from the agent window.

1. As the test customer, you'll see the notification banner.

1. Choose or tap the notification banner. You'll automatically go to the web page that contains the chat window.

1. Because you minimized your chat window earlier, you will also see a notification icon—a red dot—on the communications widget.

If you can't see the browser notification, check the following: 
+ You're using a [supported browser](add-chat-to-website.md#chat-widget-supported-browsers).
+ The notification permission is allowed/enabled on your browser for the web page with chat window.
+ The agent (or you from your agent chat session) has sent a new message/attachment while you're on a web page that is different from the one that contains the chat window. For the notification icon—a red dot—on the widget to be visible, minimize your chat window.
+ Notifications from the browser are not snoozed (temporarily dismissed).

# Programmatically disconnect the chat session of an Amazon Connect communication widget
<a name="programmatic-chat-disconnect"></a>

You can disconnect the chat session of a communication widget programmatically using 'JavaScript by calling the `disconnect` method stored to the widget's `iframe`. From the widget's host document, you can reference the `disconnect` function using the following code snippet: 

```
document.getElementById("amazon-connect-chat-widget-iframe").contentWindow.connect.ChatSession.disconnect()
```

You can readily add it to the existing widget script. Following is an example code snippet:

```
<script type="text/javascript">
  (function(w, d, x, id){
    s=d.createElement('script');
    s.src='https://your-instance-alias.my.connect.aws/connectwidget/static/amazon-connect-chat-interface-client.js';
    s.async=1;
    s.id=id;
    d.getElementsByTagName('head')[0].appendChild(s);
    w[x] =  w[x] || function() { (w[x].ac = w[x].ac || []).push(arguments) };
  })(window, document, 'amazon_connect', '...');
  amazon_connect('styles', { iconType: 'CHAT', openChat: { color: '#ffffff', backgroundColor: '#123456' }, closeChat: { color: '#ffffff', backgroundColor: '#123456'} });
  amazon_connect('snippetId', '...');
  amazon_connect('supportedMessagingContentTypes', [ 'text/plain', 'text/markdown', 'application/vnd.amazonaws.connect.message.interactive', 'application/vnd.amazonaws.connect.message.interactive.response' ]);
 
  // Add disconnect event listener
  window.addEventListener("pagehide", () => {
      document.getElementById("amazon-connect-chat-widget-iframe").contentWindow.connect.ChatSession.disconnect();
  });
</script>
```

## Implementation and use cases
<a name="implementation-chat-disconnect"></a>

Calling disconnect programmatically can be useful in multiple cases. It provides more control on when to terminate the conversation outside of manually clicking the `End Chat` button. Here are some common use cases for when to call `disconnect`.

### On close or navigation
<a name="close-chat-disconnect"></a>

A common use case would be to attach the disconnect functionality to events that fire when the browser or tab context is destroyed. `pagehide` and `beforeunload` are the common events that are fired when tearing down the browser. These are triggered when a user refreshes, navigates to a different URL or closes the tab or browser. Although both events are fired when the browser context is destroyed, there is no guarantee that the `disconnect` function can fully execute before the browser’s resources are cleaned up.

`pagehide` is a more modern page lifecycle event and is supported across all major browsers and operating systems. `beforeunload` is an alternative event to try if the `pagehide` event fails to call disconnect consistently. `beforeunload` is triggered before `pagehide` which may provide additional reliability if the `disconnect` function is failing to complete before the browser is closed. There have been reliability issues regarding `beforeunload` especially on iOS devices.

Following is an example code snippet:

```
// Call disconnect when `beforeunload` triggers
window.addEventListener("beforeunload", (event) => {
    document.getElementById("amazon-connect-chat-widget-iframe").contentWindow.connect.ChatSession.disconnect();
});

// Call disconnect when `pagehide` triggers
window.addEventListener("pagehide", (event) => {
    document.getElementById("amazon-connect-chat-widget-iframe").contentWindow.connect.ChatSession.disconnect();
});
```

### On context switching
<a name="context-chat-disconnect"></a>

Another use case would be to trigger a disconnect when the user switches contexts such as when a user switches or minimizes the tab/app or locks their screen. The `visibilitychange` event can reliably handle these scenarios where the context is no longer visible.

Following is an example code snippet:

```
window.addEventListener("visibilitychange", () => {
    if (document.visibilityState === "hidden") {
        document.getElementById("amazon-connect-chat-widget-iframe").contentWindow.connect.ChatSession.disconnect();
    } else if (document.visibilityState === "visible") {
        ...
    }
});
```

# Pass custom properties to override the defaults in the communications widget in Amazon Connect
<a name="pass-custom-styles"></a>

To further customize your chat user interface, you can override the default properties by passing your own values. For example, you can set the widget width to 400 pixels and the height to 700 pixels (in contrast to the default size of 300 pixels by 540 pixels). You can also use your preferred font colors and sizes.

## How to pass custom styles for the communications widget
<a name="chat-widget-pass-custom-styles"></a>

To pass custom styles, use the following example code block and embed it in your widget. Amazon Connect retrieves the custom styles automatically. All of the fields shown in the following example are optional.

```
amazon_connect('customStyles', {
 global: {
     frameWidth: '400px',
     frameHeight: '700px',
     textColor: '#fe3251',
     fontSize: '20px',
     footerHeight: '120px',
     typeface: "'AmazonEmber-Light', serif",
     customTypefaceStylesheetUrl: "https://ds6yc8t7pnx74.cloudfront.net/etc.clientlibs/developer-portal/clientlibs/main/css/resources/fonts/AmazonEmber_Lt.ttf",
     headerHeight: '120px',
 },
 header: {
     headerTextColor: '#541218',
     headerBackgroundColor: '#fe3',
 },
 transcript: {
     messageFontSize: '13px',
     messageTextColor: '#fe3',
     widgetBackgroundColor: '#964950',
     agentMessageTextColor: '#ef18d3',
     systemMessageTextColor: '#ef18d3',
     customerMessageTextColor: '#ef18d3',
     agentChatBubbleColor: '#111112',
     systemChatBubbleColor: '#111112',
     customerChatBubbleColor: '#0e80f2',
 },
 footer: {
     buttonFontSize: '20px',
     buttonTextColor: '#ef18d3',
     buttonBorderColor: '#964950',
     buttonBackgroundColor: '#964950',
     footerBackgroundColor: '#0e80f2',
     startCallButtonTextColor: '#541218',
     startChatButtonBorderColor: '#fe3',
     startCallButtonBackgroundColor: '#fe3',
 },
 logo: {
     logoMaxHeight: '61px',   
     logoMaxWidth: '99%',
 },
  composer: {
     fontSize: '20px', 
 },
  fullscreenMode: true // Enables fullscreen mode on the widget when a mobile screen size is detected in a web browser.
})
```

## Supported styles and constraints
<a name="chat-widget-supported-styles"></a>

The following table lists the supported custom style names and recommended value constraints. Some styles exist at both the global and component levels. For example, the `fontSize` style exists globally and in the transcript component. Component level styles have higher priority and will be honored on the chat widget.


|  Custom style name  |  Description  |  Recommended constraints  | 
| --- | --- | --- | 
|  `global.frameWidth`  |  Width of the entire widget frame  |  Minimum: 300 pixels Maximum: Window width Recommended to adjust based on window size  | 
|  `global.frameHeight`  |  height of the entire widget frame  |  Minimum: 480 pixels Maximum: Window height Recommended to adjust based on window size  | 
|  `global.textColor`  |  Color for all texts  |  Any CSS legal color value. For more information, see [CSS Legal Color Values](https://www.w3schools.com/cssref/css_colors_legal.php).  | 
|  `global.fontSize`  |  Font size for all texts  |  Recommended 12 pixels to 20 pixels for different use cases  | 
|  `global.footerHeight`  |  Height of the widget footer  |  Minimum: 50 pixels Maximum: Frame height Recommended to adjust based on frame size  | 
|  `global.typeface`  |  The typeface used in the widget.  |  Any typeface from this list: Arial, Times New Roman, Times, Courier New, Courier, Verdana, Georgia, Palatino, Garamond, Book man, Tacoma, Trebuches MS, Arial Black, Impact, Comic Sans MS. You can also add a custom typeface/font-family but you need to host the typeface file with public Read access. For example, you can view the documentation to use Amazon Ember font family in the [Amazon developer library](https://developer.amazon.com/en-US/alexa/branding/echo-guidelines/identity-guidelines/typography).   | 
|  `global.customTypefaceStylesheetUrl`  |  Location where the custom typeface file is hosted with public Read access.  |  Link to the public HTTP location where typeface file is hosted. For example, AmazonEmber Light typeface CDN location is `https://ds6yc8t7pnx74.cloudfront.net/etc.clientlibs/developer-portal/clientlibs/main/css/resources/fonts/AmazonEmber_Lt.ttf`  | 
|  `header.headerTextColor`  |  Text color for the header message  |  Any CSS legal color value. For more information, see [CSS Legal Color Values](https://www.w3schools.com/cssref/css_colors_legal.php).  | 
|  `header.headerBackgroundColor`  |  Text color for header background  |  Any CSS legal color value. For more information, see [CSS Legal Color Values](https://www.w3schools.com/cssref/css_colors_legal.php).  | 
|  `global.headerHeight`  |  Height of the widget header  |  Recommended to adjust based on using title or image logo or both.  | 
|  `transcript.messageFontSize`  |  Font size for all texts  |  Recommended 12 pixels to 20 pixels for different use cases  | 
|  `transcript.messageTextColor`  |  Text color for transcript messages  |  Any CSS legal color value. For more information, see [CSS Legal Color Values](https://www.w3schools.com/cssref/css_colors_legal.php).  | 
|  `transcript.widgetBackgroundColor`  |  Text color for transcript background  |  Any CSS legal color value. For more information, see [CSS Legal Color Values](https://www.w3schools.com/cssref/css_colors_legal.php).  | 
|  `transcript.customerMessageTextColor`  |  Text color for customer messages  |  Any CSS legal color value. For more information, see [CSS Legal Color Values](https://www.w3schools.com/cssref/css_colors_legal.php).  | 
|  `transcript.agentMessageTextColor`  |  Text color for agent messages  |  Any CSS legal color value. For more information, see [CSS Legal Color Values](https://www.w3schools.com/cssref/css_colors_legal.php).  | 
|  `transcript.systemMessageTextColor`  |  Text color for system messages  |  Any CSS legal color value. For more information, see [CSS Legal Color Values](https://www.w3schools.com/cssref/css_colors_legal.php).  | 
|  `transcript.agentChatBubbleColor`  |  Background color for agent message bubbles  |  Any CSS legal color value. For more information, see [CSS Legal Color Values](https://www.w3schools.com/cssref/css_colors_legal.php).  | 
|  `transcript.customerChatBubbleColor`  |  Background color for customer message bubbles  |  Any CSS legal color value. For more information, see [CSS Legal Color Values](https://www.w3schools.com/cssref/css_colors_legal.php).  | 
|  `transcript.systemChatBubbleColor`  |  Background color for system message bubbles  |  Any CSS legal color value. For more information, see [CSS Legal Color Values](https://www.w3schools.com/cssref/css_colors_legal.php).  | 
|  `footer.buttonFontSize`  |  Font size for the action button text  |  Recommended to adjust based on footer height  | 
|  `footer.buttonTextColor`  |  Color for the action button text  |  Any CSS legal color value. For more information, see [CSS Legal Color Values](https://www.w3schools.com/cssref/css_colors_legal.php).  | 
|  `footer.buttonBorderColor`  |  Color for the action button border  |  Any CSS legal color value. For more information, see [CSS Legal Color Values](https://www.w3schools.com/cssref/css_colors_legal.php).  | 
|  `footer.buttonBackgroundColor`  |  Color for the action button background  |  Any CSS legal color value. For more information, see [CSS Legal Color Values](https://www.w3schools.com/cssref/css_colors_legal.php).  | 
|  `footer.BackgroundColor`  |  Color for the footer background  |  Any CSS legal color value. For more information, see [CSS Legal Color Values](https://www.w3schools.com/cssref/css_colors_legal.php).  | 
|  `footer.startCallButtonTextColor`  |  Color for the start call button text  |  Any CSS legal color value. For more information, see [CSS Legal Color Values](https://www.w3schools.com/cssref/css_colors_legal.php).  | 
|  `footer.startCallButtonBorderColor`  |  Color for the start call button border  |  Any CSS legal color value. For more information, see [CSS Legal Color Values](https://www.w3schools.com/cssref/css_colors_legal.php).  | 
|  `footer.startCallButtonBackgroundColor`  |  Color for the start call button background  |  Any CSS legal color value. For more information, see [CSS Legal Color Values](https://www.w3schools.com/cssref/css_colors_legal.php).  | 
|  `logo.logoMaxHeight`  |  Max height of the logo  |  Minimum: 0 pixels Maximum: Header height Recommended to adjust based on image size and frame height  | 
|  `logo.logoMaxWidth`  |  Max width of the logo  |  Minimum: 0 pixels Maximum: Header width Recommended to adjust based on image size and frame width  | 
|  `composer.fontSize`  |  Font size for the composer text  |  Recommended 12 pixels to 20 pixels for different use cases  | 
|  `fullscreenMode`  |  Enables fullscreen mode on the widget when a mobile screen size is detected in a web browser.  |  type: boolean  | 

Following are the elements that make up the communications widget.

![\[Elements that make up the communications widget.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/chatwidget-elements.png)


## How to pass override system and bot display names and logos for the communications widget
<a name="pass-override-system"></a>

To override the System/Bot display name and logo configurations set in the Amazon Connect admin website, embed the following code block into your widget code snippet. All of the fields shown in the following example are optional.

```
amazon_connect('customDisplayNames', {
 header: {
     headerMessage: "Welcome!",
     logoUrl: "https://example.com/abc.png",
     logoAltText: "Amazon Logo Banner"
 },
 transcript: {
     systemMessageDisplayName: "Amazon System",
     botMessageDisplayName: "Alexa"
 },
 footer: {
     textInputPlaceholder: "Type Here!",     
      endChatButtonText: "End Session",      
      closeChatButtonText: "Close Chat",      
      startCallButtonText: "Start Call"
 },
})
```

### Supported properties and constraints
<a name="supported-properties-displaynames"></a>


| Custom style name | Description | Recommended constraints | 
| --- | --- | --- | 
|  `header.headerMessage`  | Text for the header message | Minimum length: 1 character Maximum length: 11 characters  Recommended to adjust based on header width | 
|  `header.logoUrl`  | URL pointing to the logo image |  Maximum length: 2048 characters Must be a valid URL pointing to a .png, .jpg or .svg file | 
|  `header.logoAltText`  | Text to override the alt attribute for the logo banner |  Maximum length: 2048 characters | 
|  `transcript.systemMessageDisplayName`  | Text to override SYSTEM\$1MESSAGE display name | Minimum length: 1 character Maximum length: 26 characters  | 
|  `transcript.botMessageDisplayName`  | Text to override BOT display name | Minimum length: 1 character Maximum length: 26 characters  | 
|  `footer.textInputPlaceholder`  | Text to override placeholder in text input | Minimum length: 1 character Maximum length: 256 characters  | 
|  `footer.endChatButtonText`  | Text to override end chat button text | Minimum length: 1 character Maximum length: 256 characters Recommended to adjust based on button width  | 
|  `footer.closeChatButtonText`  | Text to override close chat button text | Minimum length: 1 character Maximum length: 256 characters Recommended to adjust based on button width  | 
|  `footer.startCallButtonText`  | Text to override start call button text | Minimum length: 1 character Maximum length: 256 characters Recommended to adjust based on button width  | 

## Preview your communications widget with custom properties
<a name="chat-widget-preview"></a>

Make sure to preview your communications widget with the custom properties before putting it into production. Custom values can break the communications widget user interface if not set properly. We recommend testing it on different browsers and devices before releasing it to your customers.

Following are a few examples of things that might break when improper values are used and the suggested fixes.
+ **Issue:** The widget window takes up too much of the screen.

  **Fix:** Use a smaller `frameWidth` and `frameHeight`.
+ **Issue:** The font size is too small or too large.

  **Fix:** Adjust the font size.
+ **Issue:** There is a blank area below end chat (footer).

  **Fix:** Use a smaller `frameHeight` or a larger `footerHeight`.
+ **Issue:** The end chat button is too small or too big.

  **Fix:** Adjust `buttonFontSize`.
+ **Issue:** The end chat button is going outside the footer area.

  **Fix:** Use a larger `footerHeight` or a smaller `buttonFontSize`.

# Target your Amazon Connect widget button and frame with CSS/JavaScript
<a name="target-widget-button"></a>

The communication widget renders the open/close widget button and the widget frame directly on the host website. There are specific selectors that you can use to either target these elements using CSS or reference them in JavaScript. 

**Tip**  
To update the colors of the widget button, or the styles of the widget itself, use the [Amazon Connect admin website](add-chat-to-website.md#customize-chat-widget). For more customizable styles, you can [pass custom styles](pass-custom-styles.md) directly to the communications widget.

## Widget element IDs and examples
<a name="widget-elementid"></a>

The following images show how the chat widget button appears on the user's screen. The first image shows Open button to open the chat widget. The second image shows the Close button to close the chat widget.

![\[Side-by-side images of the chat widget to open and to close the chat window.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/widget-elements.png)


1.  Open widget button: `#amazon-connect-open-widget-button` 

1. Close widget button: `#amazon-connect-close-widget-button`

1. Widget frame: `#amazon-connect-widget-frame`

   1. Widget frame while open: `#amazon-connect-widget-frame.show`

   1. Widget frame while closed: `#amazon-connect-widget-frame:not(.show)`

Following is an example of a CSS style sheet that modifies these elements:

```
/* Target widget button while widget is minimized */
#amazon-connect-open-widget-button {
  ...
}

/* Target widget button while widget is showing */
#amazon-connect-close-widget-button {
  ...
}

/* Target widget frame */
#amazon-connect-widget-frame {
  ...
}

/* Target widget frame while it is showing */
#amazon-connect-widget-frame.show {
  ...
}

/* Target widget frame while it is minimized */
#amazon-connect-widget-frame:not(.show) {
  ...
}
```

Following is an example of referencing these elements using JavaScript:

```
const openWidgetButton = document.getElementById("amazon-connect-open-widget-button");
const closeWidgetButton = document.getElementById("amazon-connect-close-widget-button");

const widgetFrame = document.querySelector("#amazon-connect-widget-frame");
const openWidgetFrame = document.querySelector("#amazon-connect-widget-frame.show");
const hiddenWidgetFrame = document.querySelector("#amazon-connect-widget-frame:not(.show)");
```

# Troubleshoot issues with your Amazon Connect communications widget
<a name="ts-cw"></a>

This topic is for developers who need to investigate issues that may occur when configuring a communications widget in the Amazon Connect admin website. 

**Topics**
+ ["Something went wrong"](#sww)
+ [Customers not receiving agent messages: Network or WebSocket disconnected](#mam)
+ [Bypassing CORS when opening third-party links](#bcwotpl)

## "Something went wrong"
<a name="sww"></a>

If you see the following **Something went wrong** error message when loading your communications widget, open the browser tools to view the error logs. 

![\[An error message that says Something went wrong.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/chatwidget-error-message.png)


Following are common issues that cause this error.

### 400 Invalid request
<a name="400-invalid-request"></a>

If the logs mention a 400 invalid request, there are a few possible causes:
+ Your communications widget is not being served on an allowed domain. You must specifically state the domains where you will host your widget.
+ The request to the endpoint is not properly formatted. This usually occurs only if the contents of the embed snippet have been modified.

### 401 Unauthorized
<a name="401-unauthorized"></a>

![\[The Something went wrong error message.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/something-went-wrong.png)


If the logs mention a 401 unauthorized, this is a problem with the JSON Web Token (JWT) authentication. It displays the above error page.

After you have the JWT, you need to implement it in the `authenticate` callback function. The following example shows how to implement it if you're trying to fetch your token and then use it: 

```
amazon_connect('authenticate', function(callback) {
  window.fetch('/token').then(res => {
    res.json().then(data => {
      callback(data.data);
    });
  });
});
```

Here is a more basic version of what needs to be implemented:

```
amazon_connect('authenticate', function(callback) {
   callback(token);
});
```

For instructions on implementing JWT, see [Step 3: Confirm and copy communications widget code and security keys](add-chat-to-website.md#confirm-and-copy-chat-widget-script).

If you have implemented the callback already, the following scenarios may still cause a 401:
+ Invalid signature
+ Expired token

### 404 Not found
<a name="404-not-found"></a>

A 404 status code is typically caused when the requested resource doesn't exist:
+ An invalid widgetId is specified in the API request
+ The widgetId is valid but the associated flow has been deleted or archived
+ The widget hasn't been published, or it has been deleted

Verify that your snippet is exactly how it was copied from the Amazon Connect admin website, and none of the identifiers have changed.

If the identifiers have not changed and you are seeing a 404, contact AWS Support. 

### 500 Internal server error
<a name="500-internalservererror-chatwidget"></a>

This can be caused by your service-linked role not having the required permissions to start chat. This happens if your Amazon Connect instance was created before October 2018 because you don’t have service-linked roles set up.

**Solution**: Add the `connect:*` policy on the role that is associated with your Amazon Connect instance. For more information, see [Use service-linked roles and role permissions for Amazon Connect](connect-slr.md).

If your service-linked role has the correct permissions, contact AWS Support.

## Customers not receiving agent messages: Network or WebSocket disconnected
<a name="mam"></a>

During a chat session, a customer who is using a chat application loses their network/WebSocket connection. They quickly re-gain connection, but messages that were sent by the agent during that time aren't rendered in the customer's chat interface. 

The following image shows an example of the customer's chat interface and agent's Contact Control Panel side-by-side. A message the agent sent is not rendered in the customer's chat session. However, it appears to the agent as though the customer has received it.

![\[A message in the CCP that is not sent to the contact.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/tw-cw-001-message-not-sent.png)


If the customer's chat application loses it's network/WebSocket connection, the chat user interface must do the following to retrieve future messages as well as messages that were sent to it while disconnected: 
+ Re-establish the WebSocket connection to receive future incoming messages again.
+ Make a [chatSession.getTranscript](https://github.com/amazon-connect/amazon-connect-chatjs?tab=readme-ov-file#chatsessiongettranscript) ([getTranscripts](https://docs.aws.amazon.com/connect-participant/latest/APIReference/API_GetTranscript.html) API) request to retrieve all missing messages that were sent while the customer was disconnected.

If the agent sends a message while the customer's chat user interface is disconnected, the message is successfully stored in the Amazon Connect back end: the CCP is working as expected and messages are all recorded in transcript, but the customer's device is unable to receive messages. When the client reconnects to the WebSocket, there is a gap in messages. Future incoming messages will appear again from the WebSocket, but the gap messages are still missing unless the code explicitly makes a call to the [GetTranscript](https://docs.aws.amazon.com/connect-participant/latest/APIReference/API_GetTranscript.html) API.

### Solution
<a name="solution-network-disconnected"></a>

Use the [chatSession.onConnectionEstablished](https://github.com/amazon-connect/amazon-connect-chatjs?tab=readme-ov-file#chatsessiononconnectionestablished) event handler to call the [GetTranscript](https://docs.aws.amazon.com/connect-participant/latest/APIReference/API_GetTranscript.html) API. The `chatSession.onConnectionEstablished` event handler is triggered when the WebSocket re-connects. ChatJS has built-in heartbeat and retry logic for the WebSocket connection. Because ChatJS is not storing the transcript, however, you must add custom code to the chat user interface to manually fetch the transcript again.

The following code sample shows how to implement `onConnectionEstablished` to call `GetTranscript`.

```
import "amazon-connect-chatjs";

const chatSession = connect.ChatSession.create({
  chatDetails: {
    ContactId: "the ID of the contact",
    ParticipantId: "the ID of the chat participant",
    ParticipantToken: "the participant token",
  },
  type: "CUSTOMER",
  options: { region: "us-west-2" },
});

// Triggered when the websocket reconnects
chatSession.onConnectionEstablished(() => {
  chatSession.getTranscript({
    scanDirection: "BACKWARD",
    sortOrder: "ASCENDING",
    maxResults: 15,
    // nextToken?: nextToken - OPTIONAL, for pagination
  })
    .then((response) => {
      const { initialContactId, nextToken, transcript } = response.data;
      // ...
    })
    .catch(() => {})
});
```

```
function loadLatestTranscript(args) {
    // Documentation: https://github.com/amazon-connect/amazon-connect-chatjs?tab=readme-ov-file#chatsessiongettranscript
    return chatSession.getTranscript({
        scanDirection: "BACKWARD",
        sortOrder: "ASCENDING",
        maxResults: 15,
        // nextToken?: nextToken - OPTIONAL, for pagination
      })
      .then((response) => {
        const { initialContactId, nextToken, transcript } = response.data;
        
        const exampleMessageObj = transcript[0];
        const {
          DisplayName,
          ParticipantId,
          ParticipantRole, // CUSTOMER, AGENT, SUPERVISOR, SYSTEM
          Content,
          ContentType,
          Id,
          Type,
          AbsoluteTime, // sentTime = new Date(item.AbsoluteTime).getTime() / 1000
          MessageMetadata, // { Receipts: [{ RecipientParticipantId: "asdf" }] }
          Attachments,
          RelatedContactid,
        } = exampleMessageObj;

        return transcript // TODO - store the new transcript somewhere
      })
      .catch((err) => {
        console.log("CustomerUI", "ChatSession", "transcript fetch error: ", err);
      });
}
```

For another example, see this [open source implementation on GitHub](https://github.com/amazon-connect/amazon-connect-chat-interface/blob/c88f854073fe6dd45546585c3bfa363d3659d73f/src/components/Chat/ChatSession.js#L408). 

## Bypassing CORS when opening third-party links
<a name="bcwotpl"></a>

To enhance security, the communications widget operates within a sandbox environment. As a result, third-party links shared within the widget cannot be opened.

**Solution**

There are two options for bypassing CORS to allow third-party links to be opened.
+ **(Recommended)**

  Update the sandbox attribute to allow opening links in new tab which can be done by adding the following attribute to the code snippet:

  ```
  amazon_connect('updateSandboxAttributes', 'allow-scripts allow-same-origin allow-popups allow-downloads allow-top-navigation-by-user-activation allow-popups-to-escape-sandbox')
  ```
**Note**  
The attribute value can be updated as needed to allow for specific actions. This is an example for how to allow opening links in new tab.
+ Remove the sandbox attribute which can be done by adding the following attribute to the code snippet:

  ```
  amazon_connect('removeSandboxAttribute', true)
  ```

# Add a pre-contact or pre-chat form
<a name="add-precontact-form"></a>

You can capture customer information before starting a contact:
+ **Pre-contact form**: Add to capture information from the customer before starting a task or email contact.
+ **Pre-chat form**: Add to capture information from the customer before starting a chat contact.

After you capture the information, you can display it to the agent through the Contact Control Panel (CCP), or use it elsewhere in the flow.

To create the form, you create a custom view and use the connect action button component. For more information on views, see [Use the UI builder in Amazon Connect for resources in step-by-step guides](no-code-ui-builder.md).

The connect action button allows you to take in user input from the form and select what action to take when the form is submitted - start a task/email or chat.

# Enable post-chat survey
<a name="enable-post-chat-survey"></a>

Post-chat survey enables you to collect end customer feedback immediately after a chat conversation ends. With the **`DisconnectOnCustomerExit`** parameter in the [StartChatContact](https://docs.aws.amazon.com/connect/latest/APIReference/API_StartChatContact.html) API, you can configure automatic agent disconnection when end customer disconnects, ensuring that disconnect flow is triggered consistently regardless of which participant disconnects first.

## Implementation options
<a name="post-chat-survey-implementation"></a>

There are two ways to enable post-chat survey:

### For Custom Chat Widget
<a name="post-chat-survey-custom-builder"></a>

If you're using a custom chat implementation:

1. Upgrade to the latest version of [amazon-connect-chatjs](https://github.com/amazon-connect/amazon-connect-chatjs).

1. Add the `DisconnectOnCustomerExit` parameter to your [StartChatContact](https://docs.aws.amazon.com/connect/latest/APIReference/API_StartChatContact.html) API request:

   ```
   {
       "DisconnectOnCustomerExit": ["AGENT"],
       // ... other StartChatContact parameters
   }
   ```

### For Amazon Connect Communication Widget
<a name="post-chat-survey-communication-widget"></a>

If you're using the Amazon Connect Communication Widget:

1. Open the Amazon Connect console and navigate to **Communication widgets**.

1. Enable the post-chat survey setting through the Communication Widgets page.  
![\[The Communication Widget settings page showing the post-chat survey option.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/post-chat-survey-communication-widget.png)

## Update contact flow to add post-chat survey as a disconnect flow
<a name="post-chat-survey-disconnect-flow"></a>

To enable post-chat survey, you'll need to update the disconnect flow that's connected to your chat solution. Once configured, the survey will automatically trigger when customers end their chat sessions.

For information about creating a disconnect flow, see [Example chat scenario](web-and-mobile-chat.md#example-chat-scenario).

There are two ways to implement a survey in your disconnect flow:
+ **Option \$11: Using ShowView block** - Use the [Flow block in Amazon Connect: Show view](show-view-block.md) to display a custom survey interface.
+ **Option \$12: Using Lex** - Integrate with Amazon Lex for text-based survey collection. For more information, see [Add an Amazon Lex bot to Amazon Connect](amazon-lex.md).

**Note**  
For supervisor barge-in scenarios, ensure you add a [Flow block in Amazon Connect: Set working queue](set-working-queue.md) block before **Transfer to Queue**. Omitting it will cause chat contacts to terminate rather than transfer for this feature.  

![\[A flow diagram showing the Set Working Queue block before Transfer to Queue for supervisor barge-in scenarios.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/post-chat-survey-set-working-queue-block.png)


**Contact Trace Records**  
When a customer ends a chat session, Amazon Connect sets `disconnectReason` to `CUSTOMER_DISCONNECT` in the [ContactTraceRecord](ctr-data-model.md#ctr-ContactTraceRecord). When `DisconnectOnCustomerExit` is configured, the system generates a new contact ID (`nextContactId`) and initiates the configured disconnect flow.  
Example:  

```
{
    "contactId": "104c05e3-abscdfre",
    "nextContactId": "4cbae06d-ca5b-1234567",
    "channel": "CHAT",
    "initiationMethod": "DISCONNECT",
    "disconnectReason": "CUSTOMER_DISCONNECT"
}
```
[How contact attributes work in Amazon Connect](what-is-a-contact-attribute.md) will update in Contact Search and Contact Details.  

![\[Contact details showing the contact attributes for a post-chat survey.\]](http://docs.aws.amazon.com/connect/latest/adminguide/images/post-chat-survey-contact-attributes.png)


## Additional resources
<a name="post-chat-survey-additional-resources"></a>
+ [StartChatContact API](https://docs.aws.amazon.com/connect/latest/APIReference/API_StartChatContact.html)
+ [Sample inbound flow in Amazon Connect for the first contact experience](sample-inbound-flow.md)
+ [Example chat scenario](web-and-mobile-chat.md#example-chat-scenario)
+ [Flow block in Amazon Connect: Set working queue](set-working-queue.md)
+ [Flow block in Amazon Connect: Transfer to queue](transfer-to-queue.md)
+ [Amazon Connect ShowView](https://docs.aws.amazon.com/connect/latest/adminguide/show-view-block.html)
+ [Amazon Connect with Lex](https://docs.aws.amazon.com/connect/latest/adminguide/amazon-lex.html)
+ [How contact attributes work in Amazon Connect](what-is-a-contact-attribute.md)