Skip to content

Commit 2188b9f

Browse files
committed
add expo example app
1 parent f1a4bef commit 2188b9f

40 files changed

+10433
-6
lines changed

examples/expo-example/.gitignore

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
2+
3+
# dependencies
4+
node_modules/
5+
6+
# Expo
7+
.expo/
8+
dist/
9+
web-build/
10+
expo-env.d.ts
11+
12+
# Native
13+
.kotlin/
14+
*.orig.*
15+
*.jks
16+
*.p8
17+
*.p12
18+
*.key
19+
*.mobileprovision
20+
21+
# Metro
22+
.metro-health-check*
23+
24+
# debug
25+
npm-debug.*
26+
yarn-debug.*
27+
yarn-error.*
28+
29+
# macOS
30+
.DS_Store
31+
*.pem
32+
33+
# local env files
34+
.env*.local
35+
36+
# typescript
37+
*.tsbuildinfo
38+
39+
app-example

examples/expo-example/.npmrc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node-linker=hoisted
2+
enable-pre-post-scripts=true

examples/expo-example/README.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# Welcome to @intercom/intercom-react-native Expo Example App 👋
2+
3+
This is an [Expo](https://expo.dev) project demonstrating the integration of @intercom/intercom-react-native with React Native's New Architecture (TurboModules/Fabric).
4+
5+
## Prerequisites
6+
7+
1. Install [Expo CLI](https://docs.expo.dev/get-started/installation/#installing-expo-cli):
8+
```bash
9+
npm install -g @expo/cli
10+
```
11+
12+
2. Set up your React Native development environment as described in:
13+
- [Android environment setup](https://reactnative.dev/docs/environment-setup?package-manager=yarn&guide=native&platform=android)
14+
- [iOS environment setup](https://reactnative.dev/docs/environment-setup?package-manager=yarn&guide=native&platform=ios)
15+
16+
## Installation
17+
18+
1. Install dependencies:
19+
```bash
20+
yarn install
21+
```
22+
23+
## Configuration
24+
25+
1. Update `app.json` with your Intercom credentials:
26+
```json
27+
{
28+
"plugins": [
29+
[
30+
"@intercom/intercom-react-native",
31+
{
32+
"appId": "YOUR_APP_ID",
33+
"androidApiKey": "android_sdk-YOUR_ANDROID_API_KEY",
34+
"iosApiKey": "ios_sdk-YOUR_IOS_API_KEY"
35+
}
36+
]
37+
]
38+
}
39+
```
40+
41+
2. Update the bundle identifier and package name:
42+
- iOS: Change `ios.bundleIdentifier` in `app.json`
43+
- Android: Change `android.package` in `app.json`
44+
45+
3. (Optional) For push notifications:
46+
- iOS: Update `ios.entitlements.aps-environment` to `development` or `production`
47+
- Android: Uncomment and configure `android.googleServicesFile` if using Google Services
48+
49+
## Running the App
50+
51+
### Development Build (Recommended)
52+
53+
1. Create a development build:
54+
```bash
55+
# For iOS
56+
npx expo run:ios
57+
58+
# For Android
59+
npx expo run:android
60+
```
61+
62+
2. Start the development server:
63+
```bash
64+
yarn start
65+
```
66+
67+
### Expo Go (Limited functionality)
68+
69+
Note: Push notifications and some native features may not work in Expo Go.
70+
71+
```bash
72+
yarn start
73+
```
74+
75+
Then scan the QR code with Expo Go app on your device.
76+
77+
## Features Demonstrated
78+
79+
This example app demonstrates all major Intercom features:
80+
81+
- **User Management**: Login, logout, update user attributes
82+
- **Messaging**: Open messenger, conversations, help center
83+
- **Content Display**: Articles, carousels, surveys
84+
- **Push Notifications**: Setup and handling
85+
- **Architecture Detection**: Shows whether New Architecture is enabled
86+
- **Modern UI**: Built with NativeWind/TailwindCSS
87+
88+
## Architecture Support
89+
90+
This example supports both:
91+
- **New Architecture** (TurboModules/Fabric) - React Native 0.79+
92+
- **Legacy Architecture** (Bridge) - React Native 0.68+
93+
94+
The app automatically detects and displays which architecture is active.
95+
96+
## Troubleshooting
97+
98+
1. **Build errors**: Try clearing cache and rebuilding:
99+
```bash
100+
npx expo run:ios --clear
101+
npx expo run:android --clear
102+
```
103+
104+
2. **Pod install issues** (iOS):
105+
```bash
106+
cd ios && pod install --repo-update
107+
```
108+
109+
3. **Metro bundler issues**:
110+
```bash
111+
npx expo start --clear
112+
```
113+
114+
4. **IntercomEventEmitter null errors**: Ensure you're using a development build, not Expo Go, as native modules require compilation.
115+
116+
## Learn More
117+
118+
- [Expo documentation](https://docs.expo.dev/)
119+
- [Intercom React Native SDK](https://github.com/intercom/intercom-react-native)
120+
- [React Native New Architecture](https://reactnative.dev/docs/new-architecture-intro)

examples/expo-example/app.json

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{
2+
"expo": {
3+
"name": "expo-example",
4+
"slug": "expo-example",
5+
"version": "1.0.0",
6+
"orientation": "portrait",
7+
"icon": "./assets/images/icon.png",
8+
"scheme": "expoexample",
9+
"userInterfaceStyle": "automatic",
10+
"newArchEnabled": true,
11+
"ios": {
12+
"supportsTablet": true,
13+
"bundleIdentifier": "com.example.intercomreactnative", // Change this to your app's bundle identifier
14+
"entitlements": {
15+
"aps-environment": "production" // Change this to your app's environment
16+
}
17+
},
18+
"android": {
19+
"adaptiveIcon": {
20+
"foregroundImage": "./assets/images/adaptive-icon.png",
21+
"backgroundColor": "#ffffff"
22+
},
23+
"edgeToEdgeEnabled": true,
24+
// "googleServicesFile": "./google-services.json", // Uncomment this if you are using Google Services for push notifications
25+
"permissions": [
26+
"android.permission.READ_EXTERNAL_STORAGE",
27+
"android.permission.VIBRATE",
28+
"android.permission.READ_EXTERNAL_STORAGE",
29+
"android.permission.VIBRATE"
30+
],
31+
"package": "com.example.intercomreactnative" // Change this to your app's package name
32+
},
33+
"web": {
34+
"bundler": "metro",
35+
"output": "static",
36+
"favicon": "./assets/images/favicon.png"
37+
},
38+
"plugins": [
39+
[
40+
"@intercom/intercom-react-native",
41+
{
42+
"appId": "YOUR_APP_ID",
43+
"androidApiKey": "android_sdk-YOUR_ANDROID_API_KEY",
44+
"iosApiKey": "ios_sdk-YOUR_IOS_API_KEY"
45+
}
46+
],
47+
"expo-router",
48+
[
49+
"expo-splash-screen",
50+
{
51+
"image": "./assets/images/splash-icon.png",
52+
"imageWidth": 200,
53+
"resizeMode": "contain",
54+
"backgroundColor": "#ffffff"
55+
}
56+
]
57+
],
58+
"experiments": {
59+
"typedRoutes": true
60+
}
61+
}
62+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import React from 'react';
2+
import { SafeAreaView, ScrollView, StatusBar } from 'react-native';
3+
import * as Notifications from 'expo-notifications';
4+
5+
import { useIntercom } from '../../hooks/useIntercom';
6+
import { useNotifications } from '../../hooks/useNotifications';
7+
8+
import Header from '../../components/Header';
9+
import AuthenticationSection from '../../components/AuthenticationSection';
10+
import MessagingSection from '../../components/MessagingSection';
11+
import ContentSection from '../../components/ContentSection';
12+
import SettingsSection from '../../components/SettingsSection';
13+
import UtilitiesSection from '../../components/UtilitiesSection';
14+
import NotificationsSection from '../../components/NotificationsSection';
15+
import ArchitectureInfo from '../../components/ArchitectureInfo';
16+
import ErrorBoundary from '../../components/ErrorBoundary';
17+
18+
// Configure notifications
19+
Notifications.setNotificationHandler({
20+
handleNotification: async () => ({
21+
shouldPlaySound: false,
22+
shouldSetBadge: false,
23+
shouldShowBanner: true,
24+
shouldShowList: true,
25+
}),
26+
});
27+
28+
export default function App() {
29+
const intercom = useIntercom();
30+
const notifications = useNotifications();
31+
32+
return (
33+
<ErrorBoundary>
34+
<SafeAreaView className="flex-1 bg-gray-50">
35+
<StatusBar barStyle="dark-content" backgroundColor="#f9fafb" />
36+
37+
<Header
38+
architectureType={intercom.architectureType}
39+
loggedUser={intercom.loggedUser}
40+
count={intercom.count}
41+
/>
42+
43+
<ScrollView className="flex-1 px-6 py-4">
44+
<AuthenticationSection
45+
loggedUser={intercom.loggedUser}
46+
email={intercom.email}
47+
setEmail={intercom.setEmail}
48+
loginUnidentifiedUser={intercom.loginUnidentifiedUser}
49+
loginWithEmail={intercom.loginWithEmail}
50+
logout={intercom.logout}
51+
isLoading={intercom.isLoading}
52+
/>
53+
54+
<MessagingSection loggedUser={intercom.loggedUser} />
55+
56+
<ContentSection loggedUser={intercom.loggedUser} />
57+
58+
<SettingsSection
59+
currentTheme={intercom.currentTheme}
60+
setTheme={intercom.setTheme}
61+
launcherVisibility={intercom.launcherVisibility}
62+
toggleLauncherVisibility={intercom.toggleLauncherVisibility}
63+
bottomPadding={intercom.bottomPadding}
64+
updateBottomPadding={intercom.updateBottomPadding}
65+
/>
66+
67+
<UtilitiesSection
68+
loggedUser={intercom.loggedUser}
69+
architectureType={intercom.architectureType}
70+
/>
71+
72+
<NotificationsSection
73+
loggedUser={intercom.loggedUser}
74+
registerForPushNotificationsAsync={notifications.registerForPushNotificationsAsync}
75+
sendTestNotification={notifications.sendTestNotification}
76+
isLoading={notifications.isLoading}
77+
/>
78+
79+
<ArchitectureInfo architectureType={intercom.architectureType} />
80+
</ScrollView>
81+
</SafeAreaView>
82+
</ErrorBoundary>
83+
);
84+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { Link, Stack } from 'expo-router';
2+
import { StyleSheet, Text, View } from 'react-native';
3+
4+
export default function NotFoundScreen() {
5+
return (
6+
<>
7+
<Stack.Screen options={{ title: 'Oops!' }} />
8+
<View style={styles.container}>
9+
<Text>This screen does not exist.</Text>
10+
<Link href="/(tabs)" style={styles.link}>
11+
<Text>Go to home screen!</Text>
12+
</Link>
13+
</View>
14+
</>
15+
);
16+
}
17+
18+
const styles = StyleSheet.create({
19+
container: {
20+
flex: 1,
21+
alignItems: 'center',
22+
justifyContent: 'center',
23+
padding: 20,
24+
},
25+
link: {
26+
marginTop: 15,
27+
paddingVertical: 15,
28+
},
29+
});
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import '../global.css';
2+
3+
import { useFonts } from 'expo-font';
4+
import { Stack } from 'expo-router';
5+
import { StatusBar } from 'expo-status-bar';
6+
import { useEffect } from 'react';
7+
import { Alert, AppState, Linking } from 'react-native';
8+
import 'react-native-reanimated';
9+
10+
import Intercom from '@intercom/intercom-react-native';
11+
12+
export default function RootLayout() {
13+
const [loaded] = useFonts({
14+
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
15+
});
16+
17+
useEffect(() => {
18+
// Handle push notifications when app is active
19+
const subscription = AppState.addEventListener(
20+
'change',
21+
(nextStatus) => nextStatus === 'active' && Intercom.handlePushMessage()
22+
);
23+
24+
// Handle deep links
25+
const urlListener = Linking.addEventListener('url', (event) => {
26+
if (event) {
27+
Alert.alert('Deep Link', event.url);
28+
}
29+
});
30+
31+
return () => {
32+
subscription.remove();
33+
urlListener.remove();
34+
};
35+
}, []);
36+
37+
if (!loaded) {
38+
// Async font loading only occurs in development.
39+
return null;
40+
}
41+
42+
return (
43+
<>
44+
<Stack>
45+
<Stack.Screen name="(tabs)/index" options={{ headerShown: false }} />
46+
<Stack.Screen name="+not-found" />
47+
</Stack>
48+
<StatusBar style="auto" />
49+
</>
50+
);
51+
}
91.1 KB
Binary file not shown.
17.1 KB
Loading
1.43 KB
Loading

0 commit comments

Comments
 (0)