> ## Documentation Index
> Fetch the complete documentation index at: https://www.plain.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Customization

> Configure the chat widget's appearance, launcher, welcome screen, and customer details.

Everything the chat widget shows is configurable through `Plain.init`: the launcher, the welcome screen, the theme, and the customer details you pass in.

<Frame>
  <img src="https://mintcdn.com/plain/esnLSCL6AbjPxXFS/public/images/customization.png?fit=max&auto=format&n=esnLSCL6AbjPxXFS&q=85&s=307b5af00e06ed3c9e49d2e9abefbd24" alt="Customization in Plain" width="2400" height="1218" data-path="public/images/customization.png" />
</Frame>

## General customization

Plain's chat widget is fully customizable, so you can tailor it to match your brand and user experience. From appearance and behavior to pre-filled thread metadata and structured inputs, you can shape the chat flow to fit your support model.

* Stay on brand with color, layout, and logo options

* Capture structured data at the point of contact to help with triage and routing

* Adapt the chat interface to different use cases across your product

* Surface links to docs, forms, or key actions before a user starts a conversation

Whether you want to embed chat in a billing portal, an onboarding wizard, or a usage dashboard, the widget can adapt to fit your exact workflow and customer experience.

### General customization code

```js theme={null}
Plain.init({
  appId: 'your_chat_app_id_here',

  // Optional. Hides the launcher, you can manually show it by calling `Plain.open()` (default: false)
  hideLauncher: false,

  // Optional. A collection of links shown on the Welcome screen
  links: [
    {
      // Optional, supported icons are:
      //   'bell',
      //   'book',
      //   'bug',
      //   'bulb',
      //   'chat',
      //   'integration',
      //   'discord',
      //   'discord_muted',
      //   'email',
      //   'slack',
      //   'slack_muted',
      //   'link',
      //   'pencil',
      //   'send',
      //   'support',
      //   'error'
      icon: 'book',
      text: 'View our docs',
      url: 'https://www.plain.com/docs',
    },
  ],

  // Optional. The entry point of the Chat.
  entryPoint: {
    // Type is either 'default' or 'chat'. 'default' will open the intro screen, 'chat' opens up straight into a chat.
    type: 'chat',
    // Optional. The external ID of which chat to open. If not provided it will default to the last conversation the user had.
    externalId: 'example_external_id',
    // Optional. Prevents the user from going back to the intro screen to start a new chat.
    singleChatMode: false,
  },

  // Optional. Lets you specify which HTML element to insert the chat into.
  // When specified, launcher will be hidden by default.
  // Note: this must be a DOM Element, not a CSS selector string.
  embedAt: document.querySelector('#embed'),

  // Optional. Hides the 'Powered by Plain' branding
  hideBranding: false,

  // Optional. The color scheme of the Chat, is either 'auto', 'light', or 'dark'
  // 'auto' uses the user's browser preference to decide between light and dark mode (default: 'auto')
  theme: 'light',

  // Optional. Various styling options
  // Colors can also be passed in this format { light: '#FFFFFF', dark: '#000000' }. Based on the theme chosen by you or browser preference
  style: {
    brandColor: '#22C55E', // This will be used in various places in the chat widget such as the primary chat button and send message button
    brandBackgroundColor: '#22C55E', // Used for the background of the chat widget on the intro screen
    launcherBackgroundColor: '#000000', // These can also be passed in this format { light: '#FFFFFF', dark: '#000000' }
    launcherIconColor: '#FFFFFF',
  },

  // Optional. Logo which is shown in the header of the chat intro screen.
  // If you have uploaded a logo in your chat settings, this setting will take priority over that.
  logo: {
    // url to get the logo from
    url: 'http://example.com',
    // Optional. Alt text which is displayed on hover of the logo
    alt: 'An example logo',
  },

  // Optional. Position of the chat widget when it is floating.
  // See https://developer.mozilla.org/en-US/docs/Web/CSS/position for more information - only bottom, right, and zIndex are supported
  position: {
    right: '10px',
    bottom: '10px',
    zIndex: '1000', // Optional. Controls the stacking order of the widget
  },

  // Optional. Allows you to set fields for the threads which are created from chats
  threadDetails: {
    // See the data model documentation for more information on these fields
  },

  // Optional. Lets you customize the buttons which are used to start a new chat on the intro screen
  chatButtons: [
    // See the chat buttons documentation for more information on these fields
  ],
});
```

## Enhance your chat flows with Plain's data model

Plain's chat widget integrates directly with the platform's data model. This lets you tag and structure threads from the start, so your team can triage without reading each one first.

You can set the following on threads created from chat:

* Labels

* Priority

* Tiers

* Tenants

* External IDs

There are several places in the configuration you can add these with varying effects:

### All threads

Providing a top-level `threadDetails` object in the `Plain.init` function will set these fields on all threads created from the chat widget. You could, for example, set a label based on the page the user is on.

### Thread details code

```js theme={null}
Plain.init({
  // ...Other options

  threadDetails: {
    // Optional. Labels to be set on created threads.
    // To find a label id open the Plain app and go to 'Settings' -> 'Labels', you can select `Copy label ID` from the overflow menu on each label
    labelTypeIds: ['lt_01JDAB92EBHP3DSXS43DW96WBS'],

    // Optional. Priority to set on created threads (1 = urgent, 2 = high, 3 = normal, 4 = low)
    priority: 3,

    // Optional. A tier to be set on created threads.
    // To find a tier ID open the Plain app and go to 'Settings' -> 'Tiers'. Select a tier and then copy the ID from the URL.
    // You can also specify a tier by its external ID e.g { externalId: 'example_external_id' }
    tierIdentifier: { tierId: 'tier_01JDABCAZBDFKH7WA6WNBDSA2F' },

    // Optional. A tenant to be set on created threads.
    // To find a tenant ID open the Plain app and click 'Tenants' under 'Browse' in the left sidebar. Select a tenant and then copy the ID from the URL.
    // You can also specify a tenant by its external ID e.g { externalId: 'example_external_id' }
    tenantIdentifier: { tenantId: 'te_01HT539973HNVZFSDXWHPT8FH1' },

    // Optional. An external ID to be set on created threads.
    externalId: 'example_external_id',

    // Optional. Thread fields to be set on created threads.
    threadFields: [
      { key: 'my_string_field', type: 'STRING', stringValue: 'some value' },
      { key: 'my_bool_field', type: 'BOOL', booleanValue: true },
      { key: 'my_enum_field', type: 'ENUM', stringValue: 'option_1' },
    ]
  }
});
```

### Chat buttons

You can configure the primary chat button and any additional chat buttons that appear on the intro screen with text and an icon using the `chatButtons` array.

You can also pass `threadDetails` to a chat button to set fields on the thread when the user creates a chat from that specific button. If you provide the same field in both the top-level `threadDetails` and a chat button, any single value fields will be overridden by the chat button and any multi-value fields will be appended to.

### Chat buttons code

```js theme={null}
Plain.init({
  // ...Other options

  chatButtons: [
    {
      // Optional. The name of the icon to display, see above for full options
      icon: 'bulb',

      // The text to display on the button
      text: 'Give feedback',

      // Optional. Allows you to set fields for the threads which are created with this button. See above for full options.
      threadDetails: {},

      // Optional. Form elements which the user must fill out before sending a chat message. See below for full options.
      form: {},
    }
  ]
})
```

### Chat forms

Similar to chat buttons, chat forms allow you to set fields on the thread when the user creates a chat. These are specific to each `chatButton`.

### Chat forms code

```js theme={null}
Plain.init({
  // ...Other options
  chatButtons: [
    {
      // ...Other chat button options
      form: {
        // The fields which make up the form. All form fields must be filled in for a user to send a chat message
        fields: [
          {
            type: 'dropdown',

            // Optional. The placeholder text displayed on the dropdown
            placeholder: 'Select a topic...',

            // The options which are available in the dropdown, minimum of 1 required.
            options: [
              {
                // Optional. An icon to be displayed on the dropdown option. See above for full options.
                icon: 'bug',

                // The text which is displayed for this dropdown option
                text: 'Bug report',

                // Optional. Enables setting values on threads when this option is selected by the user. See above for full options
                threadDetails: {},
              }
            ],
          },
          {
            type: 'text',
            placeholder: 'Your order number',

            // The 'key' of the thread field that will be set
            threadFieldKey: 'order_number'
          }
        ]
      },
    }
  ]
})
```

### Additional methods

The Plain object has additional methods to provide more control over the chat widget. This may be helpful to keep the chat widget in sync with your existing application state.

### Additional methods code

```js theme={null}
// This takes the same arguments as Plain.init. It will update the chat widget in-place with the new configuration.
// Only top-level fields are updated, nested fields are not merged.
Plain.update({ ... });

// This takes the same arguments as `customerDetails` in Plain.init.
// This will update just the customer details in the chat widget. This may be useful if you have asynchronous authentication state
Plain.setCustomerDetails({ ... })

// Opens and closes the widget if using the default, floating mode
Plain.open();
Plain.close();

// These are event listeners that will be fired when the chat widget is opened or closed respectively
// These return a function that can be called to remove the listener
Plain.onOpen(() => {
  // Opened
});
Plain.onClose(() => {
  // Closed
});

// Returns whether or not the chat widget is initialized
Plain.isInitialized();

// This returns an array with debug logs that have been collected by the chat widget
// This is useful if you are contacting Plain support with an issue regarding the chat widget
// This will redact sensitive information such as customer details
Plain.exportDebugLogs();
```
