Skip to main content

Quick Start: React Native

Embed the Lovina chat widget in your React Native app using a WebView wrapper with typed events and imperative control via hooks.

Step 1: Install

The SDK is published to Lovina's private Nexus npm registry under the @lovina scope. Point that scope at the registry in your project's .npmrc:

@lovina:registry=https://packages.ailovina.com/repository/npm-releases/

Authenticate once (ask your Lovina administrator for a Nexus account first):

npm login --scope=@lovina --auth-type=legacy \
--registry=https://packages.ailovina.com/repository/npm-releases/

--auth-type=legacy is required on npm 9+. See the installation guide for CI and Yarn Berry setup.

Then install the package:

npm install @lovina/react-native-chat-sdk

Install required peer dependencies:

npm install react-native-webview

Optionally, install @react-native-async-storage/async-storage for session persistence:

npm install @react-native-async-storage/async-storage

For iOS, install CocoaPods dependencies:

cd ios && pod install

Without @react-native-async-storage/async-storage, session cookies will not persist across app restarts.

Step 2: Add the Chat Widget

import React from 'react';
import { View } from 'react-native';
import { LovinaChatWidget } from '@lovina/react-native-chat-sdk';

export default function ChatScreen() {
return (
<View style={{ flex: 1 }}>
<LovinaChatWidget
config={{
websiteToken: 'your-website-token',
baseUrl: 'https://chat-prod.ailovina.com',
}}
onEvent={(event) => {
console.log('Chat event:', event);
}}
/>
</View>
);
}

That is all you need for a basic integration. The widget handles WebView setup, cookie persistence, and external link handling automatically.

Present chat as a full-screen modal with built-in safe area handling and a close button:

import React, { useState } from 'react';
import { Button, View } from 'react-native';
import { LovinaChatModal } from '@lovina/react-native-chat-sdk';

export default function App() {
const [showChat, setShowChat] = useState(false);

return (
<View style={{ flex: 1, justifyContent: 'center' }}>
<Button title="Open Chat" onPress={() => setShowChat(true)} />
<LovinaChatModal
isVisible={showChat}
onClose={() => setShowChat(false)}
config={{
websiteToken: 'your-website-token',
baseUrl: 'https://chat-prod.ailovina.com',
}}
onEvent={(event) => console.log(event)}
/>
</View>
);
}

Hook Usage

The useLovinaChat hook provides imperative control over the widget:

import React from 'react';
import { Button, View } from 'react-native';
import { LovinaChatWidget, useLovinaChat } from '@lovina/react-native-chat-sdk';

export default function ChatScreen() {
const { ref, open, close, setUser, setLocale, reset } = useLovinaChat();

return (
<View style={{ flex: 1 }}>
<LovinaChatWidget
ref={ref}
config={{
websiteToken: 'your-website-token',
baseUrl: 'https://chat-prod.ailovina.com',
}}
/>
<View style={{ flexDirection: 'row', gap: 8, padding: 16 }}>
<Button title="Open" onPress={open} />
<Button title="Close" onPress={close} />
<Button
title="Set User"
onPress={() => setUser('user-123', { name: 'Jane', email: 'jane@example.com' })}
/>
<Button title="Reset" onPress={reset} />
</View>
</View>
);
}

Configuration Options

ParameterTypeDefaultDescription
websiteTokenstringrequiredWebsite token for this agent, from your Lovina dashboard
baseUrlstringrequiredBase URL of your Lovina instance
localestring"id"Widget locale code (3 languages supported)
colorScheme'light' | 'dark' | 'auto'"auto"Dark mode preference (follows system when "auto")
userLovinaChatUserundefinedPre-identified user
themeLovinaChatThemeundefinedTheme color, typography, and sizing overrides
brandingLovinaChatBrandingundefinedWhite-label branding overrides
textsRecord<string, unknown>undefinedUI string overrides, keyed by translation key
featuresPartial<LovinaFeatureFlags>undefinedFeature-flag overrides

Theming and White-Label Branding

<LovinaChatWidget
config={{
websiteToken: 'your-token',
baseUrl: 'https://chat-prod.ailovina.com',
theme: {
primaryColor: '#6366F1',
},
branding: {
brandName: 'Acme Support',
poweredBy: false,
},
}}
/>

See the Configuration page for the full set of theme, branding, texts, and features options.

Pre-identified Users

<LovinaChatWidget
config={{
websiteToken: 'your-token',
baseUrl: 'https://chat-prod.ailovina.com',
user: {
identifier: 'user-12345',
name: 'Jane Doe',
email: 'jane@example.com',
phoneNumber: '+6281234567890',
identifierHash: 'hmac-hash-for-verification',
customAttributes: {
plan: 'premium',
signupDate: '2025-01-15',
},
},
}}
/>

Event Handling

<LovinaChatWidget
config={config}
onEvent={(event) => {
switch (event.type) {
case 'loaded':
console.log('Widget loaded, token:', event.authToken);
break;
case 'messageReceived':
console.log('New message:', event.message);
break;
case 'unreadCountChanged':
updateBadge(event.count);
break;
case 'closed':
console.log('Chat closed, reason:', event.reason);
break;
case 'error':
console.error(`Error [${event.code}]: ${event.message}`);
break;
}
}}
/>
EventFieldsDescription
loadedauthToken?: stringWidget finished loading
messageReceivedmessage: Record<string, unknown>New message received
unreadCountChangedcount: numberUnread count changed
closedreason?: stringChat widget was closed
errorcode: string, message: stringAn error occurred

Imperative Methods

Available via useLovinaChat hook or a ref:

MethodDescription
setUser(identifier, user)Set or update the identified user
setLocale(locale)Change the widget locale
setColorScheme(mode)Change the color scheme
toggle(show)Open or close the widget
reset()Clear session and reload
reload()Reload the widget

Session Management

Sessions are persisted automatically via AsyncStorage. To clear a session:

const { reset } = useLovinaChat();
reset(); // Clears stored cookie and reloads

TypeScript

The SDK exports all types:

import type {
LovinaChatConfig,
LovinaChatUser,
ChatEvent,
LovinaChatWidgetRef,
} from '@lovina/react-native-chat-sdk';

Requirements

  • React Native 0.70+
  • React 18.0+
  • react-native-webview 13.0+
  • @react-native-async-storage/async-storage 1.19+ (optional)

Next Steps