Komo cards can be embedded into your React Native application through Komo’s NPM package @komo-tech/react-native-widgets.

Installation

npm install @komo-tech/react-native-widgets

Basic Usage

  • The quickest way to get started with embedding Komo content in react native is by using the KomoCardWidget component.
  • This component combines metadata fetching, card cover display, and modal handling for the card 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.
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 or ExperienceModal.
  • The object keys must match the Unique ID of the form field or contact property from the Komo Platform that you want to prefill.
<KomoCardWidget
  embedMetaUrl={KomoCardNativeEmbedUrl}
  containerStyle={{ maxWidth: '80%' }}
  formPrefillValues={{
    email: '[email protected]',
    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 hook and the Native embed URL copied from the platform to fetch the CardEmbedMetadata.
  • The CardEmbedMetadata has the information required to render the cover image (imageUrl) and the URL (embedUrl) that the ExperienceModal 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, you can pass that to the other components that you want to use.
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 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.
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 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.
  • If you have forced OAuth enabled, you also need to pass through the embedAuthUrl from CardEmbedMetadata.
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 without rendering our CardCover.
// ... 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 or KomoCardWidget.
  • The onWindowMessage prop exposes any window.postMessage events from the embedded experience.
  • The onKomoEvent prop exposes any 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.
<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 and KomoCardWidget components allow you to set 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.
<KomoCardWidget
  embedMetaUrl={KomoCardNativeEmbedUrl}
  extensionDataValues={{
    custom_unique_id: 'ABC123',
    custom_object: {
      some_id: 'ABC123',
      some_measure: 123456
    }
  }}
/>

Query Parameters

Pass custom query parameters (like UTM tracking parameters) to your embedded experiences. This is useful for campaign attribution, A/B testing, and analytics tracking.

Basic Usage

import { KomoCardWidget } from '@komo-tech/react-native-widgets';

<KomoCardWidget
  embedMetaUrl={KomoCardNativeEmbedUrl}
  queryParams={{
    utm_source: 'mobile-app',
    utm_medium: 'widget',
    utm_campaign: 'summer-2024',
    utm_content: 'hero-banner'
  }}
/>;

UTM Tracking Example

<KomoCardWidget
  embedMetaUrl={embedUrl}
  queryParams={{
    utm_source: 'instagram',
    utm_medium: 'social',
    utm_campaign: 'product-launch',
    utm_term: 'keyword',
    utm_content: 'story-swipe-up'
  }}
/>

Dynamic Campaign Tracking

import { KomoCardWidget } from '@komo-tech/react-native-widgets';
import { useRoute } from '@react-navigation/native';

function CampaignScreen() {
  const route = useRoute();
  const { campaignId, source } = route.params;

  return (
    <KomoCardWidget
      embedMetaUrl={embedUrl}
      queryParams={{
        utm_campaign: campaignId,
        utm_source: source,
        utm_medium: 'app'
      }}
    />
  );
}

User Segment Tracking

import { KomoCardWidget } from '@komo-tech/react-native-widgets';
import { useUser } from './hooks/useUser';

function ContestScreen() {
  const { userSegment, subscriptionTier } = useUser();

  return (
    <KomoCardWidget
      embedMetaUrl={embedUrl}
      queryParams={{
        utm_source: 'app',
        utm_content: userSegment,
        user_tier: subscriptionTier
      }}
    />
  );
}

Combining with Other Props

Query parameters work alongside form prefill and extension data:

<KomoCardWidget
  embedMetaUrl={embedUrl}
  // Prefill form fields
  formPrefillValues={{
    email: user.email,
    first_name: user.firstName
  }}
  // Add analytics data
  extensionDataValues={{
    user_id: user.id,
    account_type: user.accountType
  }}
  // Track campaign source
  queryParams={{
    utm_source: 'app',
    utm_medium: 'home-screen',
    utm_campaign: 'welcome-flow'
  }}
/>

Using with ExperienceModal

The ExperienceModal component also supports queryParams:

import { ExperienceModal } from '@komo-tech/react-native-widgets';
import { useState } from 'react';
import { Button } from 'react-native';

function CustomModal() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <>
      <Button title="Open Contest" onPress={() => setIsOpen(true)} />

      <ExperienceModal
        isOpen={isOpen}
        onClose={() => setIsOpen(false)}
        embedUrl={metadata?.embedUrl}
        queryParams={{
          utm_source: 'custom-modal',
          utm_medium: 'app'
        }}
      />
    </>
  );
}

Track users coming from deep links:

import { useEffect, useState } from 'react';
import { Linking } from 'react-native';
import { KomoCardWidget } from '@komo-tech/react-native-widgets';

function DeepLinkScreen() {
  const [queryParams, setQueryParams] = useState({});

  useEffect(() => {
    // Parse deep link URL parameters
    Linking.getInitialURL().then((url) => {
      if (url) {
        const urlObj = new URL(url);
        const params = {};
        urlObj.searchParams.forEach((value, key) => {
          params[key] = value;
        });
        setQueryParams(params);
      }
    });
  }, []);

  return (
    <KomoCardWidget
      embedMetaUrl={embedUrl}
      queryParams={{
        ...queryParams,
        utm_source: 'deep-link'
      }}
    />
  );
}

Multi-Platform Tracking

Detect and track the platform:

import { Platform } from 'react-native';
import { KomoCardWidget } from '@komo-tech/react-native-widgets';

<KomoCardWidget
  embedMetaUrl={embedUrl}
  queryParams={{
    utm_source: 'react-native',
    utm_medium: 'app',
    platform: Platform.OS, // 'ios' or 'android'
    app_version: DeviceInfo.getVersion()
  }}
/>;

Technical Details

  • Query parameters are added directly to the webview URL (no prefix)
  • All values must be strings
  • Parameters are available to analytics tools in the embedded experience
  • Can be combined with formPrefillValues and extensionDataValues
  • Supports standard UTM parameters and custom parameters

Auth0 Session Transfer

  • The KomoCardWidget component supports Auth0 authentication through the authPassthroughParams prop.
  • The ExperienceModal component supports Auth0 authentication through the embedAuthUrl and authPassthroughParams props.
    • The embedAuthUrl is typically obtained from the 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.
  • Recommended: Specify webViewProps={{ incognito: true }} to ensure user session state is cleared correctly when changing between different authenticated users.
<KomoCardWidget
    embedMetaUrl={KomoCardNativeEmbedUrl}
    authPassthroughParams={new URLSearchParams({
        session_transfer_token: 'ABC123'
    })}
    webViewProps={{ incognito: true }}
/>

// 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'
    })}
    webViewProps={{ incognito: true }}
/>

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.

API Reference

ButtonStyle

NameTypeDescriptionRequired
textstring?Text to display on the buttonOptional
backgroundColorstring?Background color of the buttonOptional
colorstring?Text color of the buttonOptional

CardCover Props

NameTypeDescriptionRequired
onClick() => voidThe callback for when the cover is clickedRequired
isLoadingbooleanWhether the cover is loadingRequired
isErrorboolean?Whether the cover is in an error stateOptional
loaderReactNode?Override the default skeleton loaderOptional
errorDisplayReactNode?Override the default error displayOptional
metaButtonStyleButtonStyle?The button style returned from the embed metadata endpointOptional
overrideButtonStyleStyleProp<ViewStyle>?Override the button styleOptional
overrideButtonTextStyleStyleProp<TextStyle>?Override the button text styleOptional
containerStyleStyleProp<ViewStyle>?Override the container styleOptional
coverImageStyleStyleProp<ImageStyle>?Override the cover image styleOptional
hideCoverButtonboolean?Whether to hide the cover buttonOptional
imageUrlstring?The url of the cover imageOptional
imageAspectRationumber?The aspect ratio of the cover imageOptional

CardEmbedMetadata

NameTypeDescriptionRequired
titlestring?The title of the cardOptional
imageUrlstring?URL of the card’s cover imageOptional
imageHeightnumber?Height of the cover image in pixelsOptional
imageWidthnumber?Width of the cover image in pixelsOptional
imageAspectRationumber?Aspect ratio of the cover imageOptional
embedUrlstring?URL for the embedded experienceOptional
embedAuthUrlstring?URL used to OAuth user before showing the embedded experienceOptional
buttonStyleButtonStyle?Styling for the card’s buttonOptional

ExperienceModal Props

NameTypeDescriptionRequired
isOpenbooleanWhether the modal is openRequired
onClose() => voidCallback for when close is requestedRequired
embedUrlstringThe URL of the embedded card experienceRequired
modalHeaderReactNodeOverride the default modal headerOptional
shareClickUrlstringOverride the url that redirects a user when clicking on a share linkOptional
appIdstringAn identifier for the embedded Komo contentOptional
formPrefillValuesRecord<string, string>Prefill values for the form within the experienceOptional
extensionDataValuesRecord<string, string | number | boolean | object>Extension data values for the experienceOptional
loadingIndicatorReactNodeOverride the default loading indicatorOptional
modalPropsModalPropsOverride the default modal propsOptional
loadingTimeoutMsnumberTimeout in milliseconds before showing error state. Defaults to 15000msOptional
errorDisplay({ onRetry }: { onRetry: () => void }) => ReactNodeOverride the default error displayOptional
onFileDownloadWebViewProps["onFileDownload"]Callback for when a file download is requested. Only applies to iOSOptional
onKomoEvent(event: KomoEvent) => voidCallback for when a Komo event is raised in the embedded experienceOptional
onWindowMessage(event: any) => voidCallback for when a window message is raised in the embedded experienceOptional
embedAuthUrlstring?The URL of the authorization endpointOptional
authPassthroughParamsURLSearchParamsPassthrough parameters to add to the auth URL as query parametersOptional
webViewPropsWebViewPropsAdditional props for the react-native-webview componentOptional
iframePropsIframePropsAdditional props for the iframe component. Only applies if the platform is webOptional

KomoCardWidget Props

NameTypeDescriptionRequired
embedMetaUrlStringThe native embed url taken from the Komo portal settings of the card to be embeddedRequired
appIdStringUseful for the embedded Komo content to identify where it’s being embeddedOptional
containerStyleStyleProp<ViewStyle>Style overrides for the container of the card coverOptional
coverImageStyleStyleProp<ImageStyle>Style overrides for the image of the card coverOptional
buttonStyleStyleProp<ViewStyle>Style overrides for the CTA button of the card coverOptional
buttonTextStyleStyleProp<TextStyle>Style overrides for the CTA button text of the card coverOptional
coverLoaderReactNodeThe loader shown while the cover is loadingOptional
coverErrorDisplayReactNodeOverride the default error display for the coverOptional
hideCoverButtonBooleanHide the CTA button of the coverOptional
modalHeaderReactNodeThe header of the modal to render instead of the defaultOptional
onError(error) => voidCallback for when an error occurs during querying the embed metadata endpointOptional
onModalClose() => voidCallback on modal closeOptional
onModalOpen() => voidCallback on modal openOptional
shareClickUrlStringOverride of the url that redirects a user when clicking on a share linkOptional
formPrefillValuesRecord<string, string>Prefill values for the form within the experienceOptional
extensionDataValuesRecord<string, string | number | boolean | object>Extension data values for the experienceOptional
onFileDownloadWebViewProps["onFileDownload"]Callback for when a file download is requested. Only applies to iOSOptional
onKomoEvent(event: KomoEvent) => voidCallback for when a Komo event is raised in the embedded experienceOptional
onWindowMessage(event: any) => voidCallback for when a window message is raised in the embedded experienceOptional
authPassthroughParamsURLSearchParamsPassthrough parameters to add to the auth URL as query parametersOptional
loadingTimeoutMsnumberTimeout in milliseconds before showing error state in the modal. Defaults to 15000msOptional
modalErrorDisplay({ onRetry }: { onRetry: () => void }) => ReactNodeOverride the default error display for the modalOptional
webViewPropsWebViewPropsAdditional props for the react-native-webview componentOptional
iframePropsIframePropsAdditional props for the iframe component. Only applies if the platform is webOptional

KomoEvent

NameTypeDescriptionRequired
eventNamestringThe name of the eventRequired
eventDataanyObject containing the event dataRequired
extensionDataRecord<string, string | number | boolean | object>Extension data raised along with the eventRequired

useFetchCardMetadata Hook

Options

NameTypeDescriptionRequired
embedMetaUrlstringThe URL of the embed metadata for the card, copied from the Komo PortalRequired
isEnabledbooleanWhether the embed metadata query is enabled. Defaults to trueOptional
onError(e: any) => voidCallback for when an error occurs during querying the embed metadata endpointOptional

Result

NameTypeDescriptionRequired
dataCardEmbedMetadata?The embed metadata for the cardOptional
isLoadingbooleanWhether the embed metadata is loadingRequired
isErrorbooleanWhether the embed metadata query failedRequired
isSuccessbooleanWhether the embed metadata query succeededRequired
refetchAsync() => Promise<void>Function to refetch the embed metadataRequired