Docs
React Native Integration Guide
Add Heyo live chat to your React Native iOS and Android apps using WebView.
This guide shows you how to add Heyo to your React Native application for both iOS and Android.
Prerequisites
Install React Native WebView:
npm install react-native-webview
For iOS, also run:
cd ios && pod install && cd ..
Installation
Create a Chat Component
Create components/HeyoChat.js:
import React from 'react';
import { Modal, SafeAreaView, TouchableOpacity, Text, StyleSheet } from 'react-native';
import { WebView } from 'react-native-webview';
const HeyoChat = ({ visible, onClose, projectId }) => {
const html = `
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<style>
body { margin: 0; padding: 0; }
#heyo-container { width: 100vw; height: 100vh; }
</style>
</head>
<body>
<div id="heyo-container"></div>
<script src="https://heyo.so/embed/script" defer data-project-id="${projectId}"></script>
<script>
window.addEventListener('load', function() {
if (window.HEYO) {
window.HEYO.show();
}
});
</script>
</body>
</html>
`;
return (
<Modal visible={visible} animationType="slide" onRequestClose={onClose}>
<SafeAreaView style={styles.container}>
<TouchableOpacity style={styles.closeButton} onPress={onClose}>
<Text style={styles.closeText}>Close</Text>
</TouchableOpacity>
<WebView
source={{ html }}
style={styles.webview}
javaScriptEnabled={true}
domStorageEnabled={true}
/>
</SafeAreaView>
</Modal>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
closeButton: {
padding: 16,
backgroundColor: '#f0f0f0',
alignItems: 'center',
},
closeText: {
fontSize: 16,
color: '#333',
},
webview: {
flex: 1,
},
});
export default HeyoChat;
Use in Your App
import React, { useState } from 'react';
import { View, Button } from 'react-native';
import HeyoChat from './components/HeyoChat';
function App() {
const [chatVisible, setChatVisible] = useState(false);
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Button title="Open Support Chat" onPress={() => setChatVisible(true)} />
<HeyoChat
visible={chatVisible}
onClose={() => setChatVisible(false)}
projectId="YOUR_PROJECT_ID"
/>
</View>
);
}
export default App;
Advanced Usage
Pass User Data
Modify the HTML in HeyoChat.js to include user information:
const HeyoChat = ({ visible, onClose, projectId, user }) => {
const html = `
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<style>
body { margin: 0; padding: 0; }
#heyo-container { width: 100vw; height: 100vh; }
</style>
</head>
<body>
<div id="heyo-container"></div>
<script src="https://heyo.so/embed/script" defer data-project-id="${projectId}"></script>
<script>
window.addEventListener('load', function() {
if (window.HEYO) {
window.HEYO.init({
projectId: '${projectId}',
user: ${JSON.stringify(user || {})}
});
window.HEYO.show();
}
});
</script>
</body>
</html>
`;
return (
// ... rest of component
);
};
Usage:
<HeyoChat
visible={chatVisible}
onClose={() => setChatVisible(false)}
projectId="YOUR_PROJECT_ID"
user={{
name: 'John Doe',
email: '[email protected]'
}}
/>
Floating Chat Button
Create a reusable chat button component:
import React, { useState } from 'react';
import { TouchableOpacity, Text, StyleSheet } from 'react-native';
import HeyoChat from './HeyoChat';
const ChatButton = ({ projectId, user }) => {
const [visible, setVisible] = useState(false);
return (
<>
<TouchableOpacity
style={styles.fab}
onPress={() => setVisible(true)}
>
<Text style={styles.fabText}>💬</Text>
</TouchableOpacity>
<HeyoChat
visible={visible}
onClose={() => setVisible(false)}
projectId={projectId}
user={user}
/>
</>
);
};
const styles = StyleSheet.create({
fab: {
position: 'absolute',
bottom: 20,
right: 20,
width: 56,
height: 56,
borderRadius: 28,
backgroundColor: '#6366f1',
justifyContent: 'center',
alignItems: 'center',
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.25,
shadowRadius: 4,
elevation: 5,
},
fabText: {
fontSize: 24,
},
});
export default ChatButton;
Handle Deep Links
Receive messages from WebView:
const HeyoChat = ({ visible, onClose, projectId }) => {
const handleMessage = (event) => {
const { data } = event.nativeEvent;
console.log('Message from chat:', data);
// Handle custom messages from the chat widget
};
return (
<Modal visible={visible} animationType="slide">
<SafeAreaView style={styles.container}>
<WebView
source={{ html }}
onMessage={handleMessage}
// ... other props
/>
</SafeAreaView>
</Modal>
);
};
TypeScript Support
Create types/heyo.d.ts:
declare module '@heyo.so/js' {
export const HEYO: {
init: (config: { projectId: string; user?: any }) => void;
show: () => void;
hide: () => void;
toggle: () => void;
};
}
TypeScript version of HeyoChat:
import React from 'react';
import { Modal, SafeAreaView, TouchableOpacity, Text, StyleSheet } from 'react-native';
import { WebView } from 'react-native-webview';
interface User {
name?: string;
email?: string;
[key: string]: any;
}
interface HeyoChatProps {
visible: boolean;
onClose: () => void;
projectId: string;
user?: User;
}
const HeyoChat: React.FC<HeyoChatProps> = ({ visible, onClose, projectId, user }) => {
// ... component implementation
};
Best Practices
- Use Modal for full-screen chat experience
- Add a close button for better UX
- Pass user context for personalized support
- Test on both iOS and Android devices
- Handle loading states in WebView
- Use SafeAreaView for notch support
Troubleshooting
WebView not loading
- Ensure
javaScriptEnabledis set totrue - Enable
domStorageEnabledfor persistent storage - Check internet connection
Chat not showing
- Verify Project ID is correct
- Check that script is loading (look for network errors)
- Ensure WebView has proper dimensions
iOS-specific issues
- Make sure you ran
pod installafter installing react-native-webview - Check Info.plist for required permissions
Android-specific issues
- Ensure internet permission is set in AndroidManifest.xml
- Check for any SSL certificate issues