@komo-tech/react-native-widgets
Version:
Embed Komo content in your React Native applications.
350 lines (281 loc) • 26.6 kB
Markdown
# 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 |