UNPKG

@komo-tech/react-native-widgets

Version:

Embed Komo content in your React Native applications.

350 lines (281 loc) 26.6 kB
# Komo React Native SDK Embed Komo content in your React Native applications. ## Installation ```sh npm install @komo-tech/react-native-widgets ``` NOTE: This package has a peer dependency on [react-native-webview](https://github.com/react-native-webview/react-native-webview), and recommends the latest major version, `13.x`. ## Basic Usage - The quickest way to get started with embedding Komo content in react native is by using the [`KomoCardWidget`](#komocardwidget-props) component. - This component combines metadata fetching, card cover display, and modal handling for the card content (i.e. experience). - The only required prop is `embedMetaUrl`. To find this in the Komo portal: - Navigate to the settings of the card to be embedded. - Select the `Embed` tab and click on `React Native code` in the right sidebar. - Copy the `Card embed meta URL` and use it as the value of the `embedMetaUrl` prop. ```js import { KomoCardWidget } from '@komo-tech/react-native-widgets'; // ... <KomoCardWidget embedMetaUrl={KomoCardNativeEmbedUrl} containerStyle={{ maxWidth: '80%' }} />; ``` ### Prefilling form details - You can pass information through to the Komo experience that will be pre-filled in any forms that the user may encounter. - Pass a plain `Record<string,string>` object of keys and values through to the `formPrefillValues` prop on [`KomoCardWidget`](#komocardwidget-props) or [`ExperienceModal`](#experiencemodal-props). - The object keys must match the Unique ID of the form field or contact property from the Komo Platform that you want to prefill. ```js <KomoCardWidget embedMetaUrl={KomoCardNativeEmbedUrl} containerStyle={{ maxWidth: '80%' }} formPrefillValues={{ email: 'email@domain.com', first_name: 'Person', last_name: 'Doe', }} /> ``` ## Advanced usage ### Metadata fetching - The first step to using embedded Komo content involves fetching the card metadata. - Use the [`useFetchCardMetadata`](#usefetchcardmetadata-hook) hook and the `Native embed URL` copied from the platform to fetch the [CardEmbedMetadata](#cardembedmetadata). - The [CardEmbedMetadata](#cardembedmetadata) has the information required to render the cover image (`imageUrl`) and the URL (`embedUrl`) that the [ExperienceModal](#experiencemodal-props) needs to render the embedded experience. - Note: you can use your own data-fetching patterns if you require more advanced data fetching handling. So long as it produces a [CardEmbedMetadata](#cardembedmetadata), you can pass that to the other components that you want to use. ```js import { useFetchCardMetadata } from '@komo-tech/react-native-widgets'; // ... rest of your component const { data, isLoading, isError } = useFetchCardMetadata({ embedMetaUrl: KomoCardNativeEmbedUrl, }); // ... use the data. ``` ### Render a Card Cover - The [`CardCover`](#cardcover-props) component is used to display the cover image of a Komo card. - It handles loading states, error states, and button display. - The component requires an `onClick` handler and `isLoading` state. - The `imageUrl` and `imageAspectRatio` props are typically obtained from the [CardEmbedMetadata](#cardembedmetadata). ```js import { CardCover } from '@komo-tech/react-native-widgets'; // ... rest of your component <CardCover imageUrl={metadata?.imageUrl} imageAspectRatio={metadata?.imageAspectRatio} isLoading={isLoading} isError={isError} onClick={() => doSomethingOnCoverClicked()} metaButtonStyle={metadata?.buttonStyle} containerStyle={{ borderRadius: 8 }} />; ``` ### Using the Experience Modal - The [`ExperienceModal`](#experiencemodal-props) component is used to display the full Komo experience in a modal overlay. - It handles loading states, error states, and communication with the embedded experience. - The component requires an `isOpen` state and `onClose` handler. - A valid `embedUrl` prop is required for the experience modal to function, and this is typically obtained from the [CardEmbedMetadata](#cardembedmetadata). - If you have forced OAuth enabled, you also need to pass through the `embedAuthUrl` from [CardEmbedMetadata](#cardembedmetadata). ```js import { ExperienceModal } from '@komo-tech/react-native-widgets'; // ... rest of your component <ExperienceModal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} embedUrl={metadata?.embedUrl} embedAuthUrl={metadata?.embedAuthUrl} loadingTimeoutMs={15000} // Optional: customize loading timeout appId="my-app" // Optional: identify where the content is embedded />; ``` ### Experience Modal example without Card Cover - You can use whichever components you want to build your desired experience. - For example, you can trigger the [`ExperienceModal`](#experiencemodal-props) without rendering our CardCover. ```js // ... rest of your component const { data, isLoading } = useFetchCardMetadata({ isEnabled, embedMetaUrl: EmbedMetaUrlFromKomoPortal, }); const [modalOpen, setModalOpen] = useState(false); // other code, e.g. some element that calls setModalOpen(true) after isLoading returns false <ExperienceModal isOpen={modalOpen} onClose={() => { setModalOpen(false); }} embedUrl={data?.embedUrl} />; ``` ### Listening for events from the embedded experience - You can listen for events from the embedded experience by using the `onWindowMessage` or `onKomoEvent` props on the [`ExperienceModal`](#experiencemodal-props) or [`KomoCardWidget`](#komocardwidget-props). - The `onWindowMessage` prop exposes any `window.postMessage` events from the embedded experience. - The `onKomoEvent` prop exposes any [User Interaction Events](https://developers.komo.tech/user-interaction-events) from the embedded experience. - Note: User Interaction Events will also appear in the `onWindowMessage` callback. `onKomoEvent` is a more convenient way to listen for Komo User Interaction Events from the embedded experience. ```js <ExperienceModal isOpen={modalOpen} onClose={() => { setModalOpen(false); }} embedUrl={data?.embedUrl} onKomoEvent={(event) => { console.log('Komo event received:', event); }} onWindowMessage={(event) => { console.log('Window message received:', event); }} /> ``` ### Extension Data - The [`ExperienceModal`](#experiencemodal-props) and [`KomoCardWidget`](#komocardwidget-props) components allow you to set [extension data](https://developers.komo.tech/user-interaction-events/extension-data) on the user interaction events. - The `extensionDataValues` prop is a plain `Record<string, string | number | boolean | object>` object. - Make sure PII is not passed in as extension data, as it is passed directly to your tag manager integrations. ```js <KomoCardWidget embedMetaUrl={KomoCardNativeEmbedUrl} extensionDataValues={{ custom_unique_id: 'ABC123', custom_object: { some_id: 'ABC123', some_measure: 123456 } }} /> ``` ### Auth0 Session Transfer - The [`KomoCardWidget`](#komocardwidget-props) component supports Auth0 authentication through the `authPassthroughParams` prop. - The [`ExperienceModal`](#experiencemodal-props) component supports Auth0 authentication through the `embedAuthUrl` and `authPassthroughParams` props. - The `embedAuthUrl` is typically obtained from [CardEmbedMetadata](#cardembedmetadata). - Pre-requisites: - Auth0 SSO must be configured on the Komo Hub, and "Force Embed Auth" must be enabled under Embed SDK settings on the hub. - Pass a fresh session transfer token to the `authPassthroughParams` prop, e.g. `session_transfer_token: 'ABC123'`. - With this setup, the user will be redirected to Auth0 to authenticate when the experience modal is opened, before being redirected back to the embedded experience. - The session transfer token must be obtained immediately before opening the experience modal, since it has a short 60 second lifespan. ```js <KomoCardWidget embedMetaUrl={KomoCardNativeEmbedUrl} authPassthroughParams={new URLSearchParams({ session_transfer_token: 'ABC123' })} /> // or if using the ExperienceModal directly <ExperienceModal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)} embedUrl={metadata?.embedUrl} embedAuthUrl={metadata?.embedAuthUrl} authPassthroughParams={new URLSearchParams({ session_transfer_token: 'ABC123' })} /> ``` #### Error handling - If the `session_transfer_token` passed to Auth0 is used, invalid, or expired, then the users will end up being shown the ExperienceModal `errorDisplay`, which includes a built-in retry button. - If you don't provide an `errorDisplay` override, the retry function will just attempt to reload the experience with the current parameters and will most likely fail again. - We recommend that you provide a custom `errorDisplay` so that you can handle `session_transfer_token` regeneration before trying to load the content again. ## Metadata model ### CardEmbedMetadata | Property | Type | Description | | ------------------ | ------------ | ------------------------------------------------------------- | | `title` | string? | The title of the card | | `imageUrl` | string? | URL of the card's cover image | | `imageHeight` | number? | Height of the cover image in pixels | | `imageWidth` | number? | Width of the cover image in pixels | | `imageAspectRatio` | number? | Aspect ratio of the cover image | | `embedUrl` | string? | URL for the embedded experience | | `embedAuthUrl` | string? | URL used to OAuth the user before showing the embedded experience | | `buttonStyle` | ButtonStyle? | Styling for the card's button | ### ButtonStyle | Property | Type | Description | | ----------------- | ------- | ------------------------------ | | `text` | string? | Text to display on the button | | `backgroundColor` | string? | Background color of the button | | `color` | string? | Text color of the button | ## Hooks ### useFetchCardMetadata A hook for fetching card metadata from the Komo platform. #### Options | Property | Type | Required | Description | | -------------- | ---------------- | -------- | ----------------------------------------------------------------------------- | | `embedMetaUrl` | string | Yes | The URL of the embed metadata for the card, copied from the Komo Portal | | `isEnabled` | boolean | No | Whether the embed metadata query is enabled. Defaults to true | | `onError` | (e: any) => void | No | Callback for when an error occurs during querying the embed metadata endpoint | #### Result | Property | Type | Description | | -------------- | ------------------- | ------------------------------------------ | | `data` | CardEmbedMetadata? | The embed metadata for the card | | `isLoading` | boolean | Whether the embed metadata is loading | | `isError` | boolean | Whether the embed metadata query failed | | `isSuccess` | boolean | Whether the embed metadata query succeeded | | `refetchAsync` | () => Promise<void> | Function to refetch the embed metadata | ## Components ### CardCover Props | Property | Type | Required | Description | | ------------------------- | ---------------------- | -------- | ---------------------------------------------------------- | | `onClick` | () => void | Yes | The callback for when the cover is clicked | | `isLoading` | boolean | Yes | Whether the cover is loading | | `isError` | boolean? | No | Whether the cover is in an error state | | `loader` | ReactNode? | No | Override the default skeleton loader | | `errorDisplay` | ReactNode? | No | Override the default error display | | `metaButtonStyle` | ButtonStyle? | No | The button style returned from the embed metadata endpoint | | `overrideButtonStyle` | StyleProp<ViewStyle>? | No | Override the button style | | `overrideButtonTextStyle` | StyleProp<TextStyle>? | No | Override the button text style | | `containerStyle` | StyleProp<ViewStyle>? | No | Override the container style | | `coverImageStyle` | StyleProp<ImageStyle>? | No | Override the cover image style | | `hideCoverButton` | boolean? | No | Whether to hide the cover button | | `imageUrl` | string? | No | The url of the cover image | | `imageAspectRatio` | number? | No | The aspect ratio of the cover image | ### ExperienceModal Props | Property | Type | Required | Description | | ------------------- | --------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `isOpen` | boolean | Yes | Whether the modal is open | | `onClose` | () => void | Yes | Callback for when close is requested | | `embedUrl` | string | Yes | The URL of the embedded card experience | | `modalHeader` | ReactNode | No | Override the default modal header | | `shareClickUrl` | string | No | Override the url that redirects a user when clicking on a share link | | `appId` | string | No | An identifier for the embedded Komo content | | `formPrefillValues` | Record<string, string> | No | Prefill values for the form within the experience | | `loadingIndicator` | ReactNode | No | Override the default loading indicator | | `modalProps` | ModalProps | No | Override the default modal props | | `loadingTimeoutMs` | number | No | Timeout in milliseconds before showing error state. Defaults to 15000ms | | `errorDisplay` | ({ onRetry }: { onRetry: () => void }) => ReactNode | No | Override the default error display | | `onFileDownload` | WebViewProps['onFileDownload'] | No | Callback for when a file download is requested. Only applies to iOS. See react-native-webview docs for more details | | `onKomoEvent` | (eventData: KomoEvent) => void | No | Callback for when a komo-event is raised in the embedded experience | | `onWindowMessage` | (eventData: any) => void | No | Callback for when a window message is raised in the embedded experience. Note that komo-events are also window messages, so this callback will be called for komo-events as well | | `extensionDataValues` | Record<string, string \| number \| boolean \| object> | No | Extension data to be included with user interaction events. Avoid including PII as this data is passed directly to tag manager integrations. | | `embedAuthUrl` | string | No | The URL of the authorization endpoint. If provided, the experience modal will first load the auth URL, then redirect to the embed URL. Typically obtained from CardEmbedMetadata | | `authPassthroughParams` | URLSearchParams | No | Passthrough parameters to add to the auth URL as query parameters. For example, an Auth0 session transfer token can be added to the auth URL. | | `webViewProps` | WebViewProps | No | Additional props for the react-native-webview component. Only applies if the platform is not web. | | `iframeProps` | IframeProps | No | Additional props for the iframe component. Only applies if the platform is web. | ### KomoCardWidget Props | Property | Type | Required | Description | | ------------------- | ------------------------------ | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `embedMetaUrl` | string | Yes | The URL of the embed metadata for the card, copied from the Komo Portal | | `appId` | string | No | An identifier for the embedded Komo content | | `containerStyle` | StyleProp<ViewStyle> | No | Override the container style | | `coverImageStyle` | StyleProp<ImageStyle> | No | Override the cover image style | | `buttonStyle` | StyleProp<ViewStyle> | No | Override the button style | | `buttonTextStyle` | StyleProp<TextStyle> | No | Override the button text style | | `coverLoader` | ReactNode | No | Override the default loader for the cover | | `coverErrorDisplay` | ReactNode | No | Override the default error display for the cover | | `hideCoverButton` | boolean | No | Whether to hide the cover button. Defaults to false | | `modalHeader` | ReactNode | No | Override the default modal header | | `onError` | (e: any) => void | No | Callback for when an error occurs during querying the embed metadata endpoint | | `onModalClose` | () => void | No | Callback for when the modal is closed | | `onModalOpen` | () => void | No | Callback for when the modal is opened | | `shareClickUrl` | string | No | Override the url that redirects a user when clicking on a share link | | `formPrefillValues` | Record<string, string> | No | Prefill values for the form within the experience | | `onFileDownload` | WebViewProps['onFileDownload'] | No | Callback for when a file download is requested. Only applies to iOS. See react-native-webview docs for more details | | `onKomoEvent` | (eventData: KomoEvent) => void | No | Callback for when a komo-event is raised in the embedded experience | | `onWindowMessage` | (eventData: any) => void | No | Callback for when a window message is raised in the embedded experience. Note that komo-events are also window messages, so this callback will be called for komo-events as well | | `extensionDataValues` | Record<string, string \| number \| boolean \| object> | No | Extension data to be included with user interaction events. Avoid including PII as this data is passed directly to tag manager integrations. | | `authPassthroughParams` | URLSearchParams | No | Passthrough parameters to add to the auth URL as query parameters. For example, an Auth0 session transfer token can be added to the auth URL. | | `loadingTimeoutMs` | number | No | Timeout in milliseconds before showing error state in the modal. Defaults to 15000ms | | `modalErrorDisplay` | ({ onRetry }: { onRetry: () => void }) => ReactNode | No | Override the default error display for the modal | | `webViewProps` | WebViewProps | No | Additional props for the react-native-webview component. Only applies if the platform is not web. | | `iframeProps` | IframeProps | No | Additional props for the iframe component. Only applies if the platform is web. | ## Other models ### KomoEvent | Property | Type | Description | | ----------- | ------ | --------------------------------------- | | `eventName` | string | The name of the Komo event | | `eventData` | any | The data associated with the Komo event | | `extensionData` | Record<string, string \| number \| boolean \| object> | The extension data raised along with the event |