# Chat Use the Chat component to create real-time chat applications. > Note: The Chat component can only be added to the chat targets of [checkout](/docs/api/checkout-ui-extensions/latest/targets/overlays/purchase-checkout-chat-render) and [Thank you](/docs/api/checkout-ui-extensions/latest/targets/overlays/purchase-thank-you-chat-render) pages. ### Basic Chat ```tsx import { reactExtension, Chat, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.chat.render', () => <Extension />, ); // This component requires the configuration of the `extensions.targeting.preloads.chat` in the extensions configuration file. // Its value will be used as the `src` attribute of the Chat component. function Extension() { return <Chat inlineSize={100} blockSize={50} />; } ``` ```js import {extension, Chat} from '@shopify/ui-extensions/checkout'; // This component requires the configuration of the `extensions.targeting.preloads.chat` in the extensions configuration file. // Its value will be used as the `src` attribute of the Chat component. export default extension('purchase.checkout.chat.render', (root) => { const chat = root.createComponent(Chat, { inlineSize: 100, blockSize: 50, }); root.appendChild(chat); }); ``` ## ChatProps ### ChatProps ### accessibilityLabel A label that describes the purpose or contents of the component. When set, it will be announced to users using assistive technologies and will provide them with more context. ### blockSize Adjust the block size. Checkout imposes [sizing restrictions](/docs/apps/build/checkout/chat#component-states) for the component, therefore the size set may not be the actual size rendered. `number`: size in pixels. Learn more about [block size on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/block-size). ### id A unique identifier for the component. ### inlineSize Adjust the inline size. Checkout imposes [sizing restrictions](/docs/apps/build/checkout/chat#component-states) for the component, therefore the size set may not be the actual size rendered. `number`: size in pixels. Learn more about [inline size on MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/inline-size). ### onMessage Callback when the embedded page sends a message. ### onReady Callback when the embedded page is ready and a message port has been created to communicate with the host page. ### MessageEvent ### data The data sent by the message emitter (the embedded page). Learn more about [MessageEvent data on MDN](https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/data). ### origin A string representing the origin of the message emitter (the embedded page). Learn more about [MessageEvent origin on MDN](https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent/origin). ### ReadyEvent ### postMessage A function to send messages to the embedded page. Learn more about [postMessage on MDN](https://developer.mozilla.org/en-US/docs/Web/API/MessagePort/postMessage). ## Examples Use the Chat component to create real-time chat applications. > Note: The Chat component can only be added to the chat targets of [checkout](/docs/api/checkout-ui-extensions/latest/targets/overlays/purchase-checkout-chat-render) and [Thank you](/docs/api/checkout-ui-extensions/latest/targets/overlays/purchase-thank-you-chat-render) pages. ### A very common action in your application will be to request a resize of the iframe. This is done through the App Bridge `resizeTo()` method. The following example resizes the iframe following the click of an activator button to show a dialog window. ### Resize the Chat iframe from the hosted application ```tsx import {reactExtension, Chat} from '@shopify/ui-extensions-react/checkout'; export default reactExtension('purchase.checkout.chat.render', () => ( <Extension /> )); function Extension() { return <Chat inlineSize={150} blockSize={50} />; } ``` ```html <!doctype html> <html lang="en"> <head> <script src="https://cdn.shopify.com/shopifycloud/checkout-web/assets/app-bridge-checkout.js"></script> <style> .dialog { display: none; } .visible { display: block; } </style> </head> <body> <dialog class="dialog"> How can we help you today? <button class="btn-close">Close</button> </dialog> <button class="btn-activator">Chat with us</button> <script type="text/javascript"> const btnActivator = document.querySelector('.btn-activator'); const btnClose = document.querySelector('.btn-close'); const dialog = document.querySelector('.dialog'); // bind actions to the buttons btnActivator.addEventListener('click', toggleDialog); btnClose.addEventListener('click', toggleDialog); function toggleDialog() { // if the dialog is visible, // - hide the dialog // - resize the iframe to the button's size if (dialog.classList.contains('visible')) { dialog.classList.remove('visible'); shopify !== undefined && window.resizeTo(150, 50); // if the dialog is not visible, // - resize the iframe to the desired dialog's size // - then show the dialog } else { shopify !== undefined && window.resizeTo(415, 700); dialog.classList.add('visible'); } } </script> </body> </html> ``` ### Information can be passed between the hosted application and the UI extension through App Bridge. [Extensions API](/docs/api/checkout-ui-extensions/unstable#extension-apis) are available in the UI extension and can be shared through that method. ### Communicate information between the hosted application and the UI extension ```tsx import { reactExtension, useShippingAddress, Chat, } from '@shopify/ui-extensions-react/checkout'; import {retain} from '@remote-ui/rpc'; import type {ReadyEvent} from '@shopify/ui-extensions-react/checkout'; export default reactExtension('purchase.checkout.chat.render', () => ( <Extension /> )); function Extension() { /** * Use the `useShippingAddress` hook to access the first name of the buyer. */ const {firstName} = useShippingAddress(); /** * Define a variable to store the `postMessage` function * so we can re-use outside of the onReady callback later if needed. */ let postMessage; return ( <Chat inlineSize={150} blockSize={50} onReady={({postMessage: postMessageParam}: ReadyEvent) => { /** * Save the `postMessage` function to the variable defined earlier. */ postMessage = postMessageParam; retain(postMessage); /** * When the communication channel is ready, send a message to the hosted application * using the `postMessage` provided as parameter. */ postMessage({ action: 'ping', buyer: { firstName, }, }); }} onMessage={(event: Event) => { /** * Listen for messages from the hosted application. * If the action is `pong`, the communication channel is successful. */ if (event.data.action === 'pong') { console.log('Messaging channel successful'); } }} /> ); } ``` ```js // Create a variable to store the buyer's first name. // We'll be able to use this to personalize the chat experience. let buyerFirstName; // In the hosted application Javascript, listen for messages from the UI extension. shopify.extension.port.onMessage = async (event) => { // if the message's data has a ping action, respond with a pong if (event.data.action === 'ping') { buyerFirstName = event.data.buyer.firstName; await shopify.extension.port.postMessage({ action: 'pong', }); } }; // Ensure the messagePort is ready to start sending and receiving messages. shopify.extension.port.start(); ``` ## App Bridge for checkout The App Bridge script for checkout provides APIs that enables a secure communication channel between the Shopify checkout and the embedded application within the Chat iframe. It also offers convenient methods to perform common actions like resizing the iframe from within the application. After App Bridge is [set up](#about-app-bridge) in your app, you have access to the `shopify` global variable. This variable exposes the following App Bridge functionalities and configuration information: ### AppBridge ### config The static configuration values that will not change during runtime. ### extension The references and APIs to the UI extension that helped bootstrap the iframe. ### idToken The ID token providing a set of claims as a signed [JSON Web Token (JWT)](https://openid.net/specs/openid-connect-core-1_0.html#IDToken%5C) with a TTL of 5 minutes. It can be used to ensure that requests came from a Shopify authenticated user. See the [ID Token documentation](/docs/apps/build/authentication-authorization/session-tokens) for more information. ### platform The platform or application that the app is embedded within. ### surface The Shopify surface that the app is embedded within. ### visitor Information about the current visitor. ### Config ### locale The locale of the shop that’s embedding the app. ### Extension ### handle The unique handle name of the UI extension as defined by the developer. Learn more about [extension configuration](/docs/api/checkout-ui-extensions/latest/configuration#how-it-works). ### port A MessagePort instance for communicating directly to and from the UI Extension that created the iframe. It will need to be started to begin receiving messages. Learn more about [MessagePort on MDN](https://developer.mozilla.org/en-US/docs/Web/API/MessagePort). ### resizeTo Set an iframe’s size. Depending on the context, the host page may decide to apply or ignore the new sizes. For example, if the iframe is meant to fill its parent container the host would ignore the request. Conversely, if the parent container allows the iframe to fill it the host would apply the new size. Alias to `window.resizeTo()`, available here for feature discovery by the embedding app. Learn more about [resizeTo() on MDN](https://developer.mozilla.org/en-US/docs/Web/API/Window/resizeTo). ### Visitor ### id The unique token of a given user across all surfaces in a shop, present if processing permission is provided. ## Examples Use the Chat component to create real-time chat applications. > Note: The Chat component can only be added to the chat targets of [checkout](/docs/api/checkout-ui-extensions/latest/targets/overlays/purchase-checkout-chat-render) and [Thank you](/docs/api/checkout-ui-extensions/latest/targets/overlays/purchase-thank-you-chat-render) pages. ### A very common action in your application will be to request a resize of the iframe. This is done through the App Bridge `resizeTo()` method. The following example resizes the iframe following the click of an activator button to show a dialog window. ### Resize the Chat iframe from the hosted application ```tsx import {reactExtension, Chat} from '@shopify/ui-extensions-react/checkout'; export default reactExtension('purchase.checkout.chat.render', () => ( <Extension /> )); function Extension() { return <Chat inlineSize={150} blockSize={50} />; } ``` ```html <!doctype html> <html lang="en"> <head> <script src="https://cdn.shopify.com/shopifycloud/checkout-web/assets/app-bridge-checkout.js"></script> <style> .dialog { display: none; } .visible { display: block; } </style> </head> <body> <dialog class="dialog"> How can we help you today? <button class="btn-close">Close</button> </dialog> <button class="btn-activator">Chat with us</button> <script type="text/javascript"> const btnActivator = document.querySelector('.btn-activator'); const btnClose = document.querySelector('.btn-close'); const dialog = document.querySelector('.dialog'); // bind actions to the buttons btnActivator.addEventListener('click', toggleDialog); btnClose.addEventListener('click', toggleDialog); function toggleDialog() { // if the dialog is visible, // - hide the dialog // - resize the iframe to the button's size if (dialog.classList.contains('visible')) { dialog.classList.remove('visible'); shopify !== undefined && window.resizeTo(150, 50); // if the dialog is not visible, // - resize the iframe to the desired dialog's size // - then show the dialog } else { shopify !== undefined && window.resizeTo(415, 700); dialog.classList.add('visible'); } } </script> </body> </html> ``` ### Information can be passed between the hosted application and the UI extension through App Bridge. [Extensions API](/docs/api/checkout-ui-extensions/unstable#extension-apis) are available in the UI extension and can be shared through that method. ### Communicate information between the hosted application and the UI extension ```tsx import { reactExtension, useShippingAddress, Chat, } from '@shopify/ui-extensions-react/checkout'; import {retain} from '@remote-ui/rpc'; import type {ReadyEvent} from '@shopify/ui-extensions-react/checkout'; export default reactExtension('purchase.checkout.chat.render', () => ( <Extension /> )); function Extension() { /** * Use the `useShippingAddress` hook to access the first name of the buyer. */ const {firstName} = useShippingAddress(); /** * Define a variable to store the `postMessage` function * so we can re-use outside of the onReady callback later if needed. */ let postMessage; return ( <Chat inlineSize={150} blockSize={50} onReady={({postMessage: postMessageParam}: ReadyEvent) => { /** * Save the `postMessage` function to the variable defined earlier. */ postMessage = postMessageParam; retain(postMessage); /** * When the communication channel is ready, send a message to the hosted application * using the `postMessage` provided as parameter. */ postMessage({ action: 'ping', buyer: { firstName, }, }); }} onMessage={(event: Event) => { /** * Listen for messages from the hosted application. * If the action is `pong`, the communication channel is successful. */ if (event.data.action === 'pong') { console.log('Messaging channel successful'); } }} /> ); } ``` ```js // Create a variable to store the buyer's first name. // We'll be able to use this to personalize the chat experience. let buyerFirstName; // In the hosted application Javascript, listen for messages from the UI extension. shopify.extension.port.onMessage = async (event) => { // if the message's data has a ping action, respond with a pong if (event.data.action === 'ping') { buyerFirstName = event.data.buyer.firstName; await shopify.extension.port.postMessage({ action: 'pong', }); } }; // Ensure the messagePort is ready to start sending and receiving messages. shopify.extension.port.start(); ```