Skip to main content

React Native Demo Project

See how easy it is to integrate high-performance ads into your React Native app using our lightweight SDK.

Requirements

  • React Native: 0.73.2 or later

Getting started

1. Installation

To get started, you will need to set up a publisher account to get a publisherToken and code.
# Install the SDK
npm install @kontextso/sdk-react-native

# Install required peer dependencies
npm install react-native-device-info react-native-webview @react-native-community/netinfo

2. Initialize AdsProvider

The AdsProvider handles all data-fetching logic and must have access to the chat messages. Place it high enough in your component tree so it can contain all ad placements.
import * as React from 'react'
import { useState } from 'react'
import { View } from 'react-native'
import { AdsProvider } from '@kontextso/sdk-react-native'

interface Message {
  id: string
  role: 'user' | 'assistant'
  content: string
  createdAt: Date
}

function App() {
  const [messages, setMessages] = useState<Message[]>([])

  return (
    <AdsProvider
      publisherToken="<publisher-token>"
      messages={messages}
      userId='user-1234'
      conversationId='conv-5678'
      enabledPlacementCodes={['inlineAd']}
      character={{
        id: 'character-1234',
        name: 'John Doe',
        avatarUrl: 'https://example.com/avatar.png',
        greeting: 'Hello, how can I help you today?'
      }}
      regulatory={{
        coppa: 0,
        // ... other regulatory properties
      }}
      onEvent={({ name, code, payload }) => {
        // process events
      }}
    >
      <TheRestOfYourApplication />
    </AdsProvider>
  )
}

3. Set up IFA (Identifier for Advertisers)

The SDK automatically reads and forwards the IFA with each ad request once the user has granted permission. To enable this, you need to complete a one-time setup on each platform.

iOS

Apple requires a usage description before the ATT (App Tracking Transparency) prompt can be shown. Add the following to your ios/<YourApp>/Info.plist:
<key>NSUserTrackingUsageDescription</key>
<string>We use your advertising identifier to show you more relevant ads.</string>
Without this key your app will crash on iOS 14+. The string is displayed in the system permission dialog, so make sure it clearly explains why tracking is needed.
The SDK calls ATTrackingManager.requestTrackingAuthorization automatically. To avoid App Store rejection, ensure the prompt is triggered at a natural point in your app flow (e.g. after onboarding) rather than immediately on launch.
The ATT prompt requires the app to be in an active state to appear. Initializing the SDK too early (e.g. before the root component is mounted) may silently suppress the prompt. Initialize the SDK only after the app becomes active.

Android

The AD_ID permission is automatically included via manifest merger from the SDK — no changes to your AndroidManifest.xml are required. No runtime prompt is required — this is an install-time permission.
If your app targets Android 13+ (API level 33+) and you have set tools:node="remove" on the AD_ID permission anywhere in your manifest configuration, remove that override or the advertising identifier will not be accessible.

4. Set up SKAdNetwork (iOS only)

SKAdNetwork (SKAN) is Apple’s privacy-preserving install attribution framework. To allow DSPs to measure ad conversions on iOS, you need to add their SKAdNetwork identifiers to your ios/<YourApp>/Info.plist.
<key>SKAdNetworkItems</key>
<array>
  <dict>
    <key>SKAdNetworkIdentifier</key>
    <string>XXX.skadnetwork</string>
  </dict>
  <!-- Add all provided identifiers here -->
</array>
The full list of required SKAdNetwork identifiers will be provided during onboarding. Make sure to add all of them, as missing an identifier means conversions from that DSP will not be attributed.
If your app already has an existing SKAdNetworkItems array, do not replace it — append the new identifiers to the existing list to avoid breaking attribution for other ad networks you may be running.

5. Show your first ad

An ad slot is a designated area in your UI where an ad can be rendered. In most cases, it appears below a chat message. During onboarding, you’ll receive a unique code for each ad slot you plan to use. Copy the markup <InlineAd /> and place it in your application where it should be rendered. Don’t forget to assign messageId as a unique identifier. For example, if you have a MessageList component, you can show an ad after each message like this (every message will have a unique ad displayed because of messageId).
function MessageList({ messages }: { messages: Message[] }) {
  return (
    <View>
      {messages.map((m) => (
        <View key={m.id}>
          <Message message={m} />
          <InlineAd code="<your-code>" messageId={m.id} />
        </View>
      ))}
    </View>
  )
}

API documentation

AdsProvider properties

publisherToken
string
required
Your unique publisher token.
messages
array
required
List of messages between the assistant and the user.
userId
string
required
Unique identifier that remains the same for the user’s lifetime (used for retargeting and rewarded ads).
userEmail
string
Email of the user.
conversationId
string
required
Unique ID of the conversation.
enabledPlacementCodes
array
required
Placement codes enabled for the conversation. Example: ['inlineAd'].
character
object
Character object used in this conversation.
regulatory
object
Regulatory compliance information.TCF (Transparency and Consent Framework) signals — gdpr and gdprConsent — are handled automatically by the SDK if you have a TCF-compliant CMP (Consent Management Platform) integrated in your app. You do not need to set these manually.
variantId
string
Publisher-provided identifier for the user cohort (for A/B testing).
onEvent
function
Callback triggered when an event occurs. See Supported events for more details.
isDisabled
boolean
Flag indicating if the ads are disabled.Note: This does not disable the display of old ads; that behavior is controlled by staleAdsHandling.
staleAdsHandling
string
Determines how stale ads (ads not linked to the latest message) are handled.
  • preserve - keep displaying the last anchored ad until it’s replaced by a new ad
  • hide (default) - hide the ad when it becomes stale

InlineAd properties

code
string
required
Placement code provided during onboarding.
messageId
string
required
Unique ID of the message.
theme
string
Theme of the ad, e.g. light or dark.
wrapper
function
Wrapper function to wrap the ad content.

Supported Events

ad.clicked

The user has clicked the ad.

ad.viewed

The user has viewed the ad.

ad.filled

Ad is available.

ad.no-fill

Ad is not available.

ad.render-started

Triggered before the first token is received.

ad.render-completed

Triggered after the last token is received.

ad.error

Triggered when an error occurs.

reward.granted

Triggered when the user receives a reward.

video.started

Triggered when the video playback starts.

video.completed

Triggered when the video playback finishes.

Guides

Handling no-fill events

You can notify when the ad is not available by using the onEvent callback.
<AdsProvider
  // ...
  onEvent={({ name, payload }) => {
    if (name === 'ad.no-fill') {
      console.log('Ad is not available');
    }
  }}
/>