@octopus-community/react-native
v1.9.1
Published
React Native module for the Octopus Community SDK
Readme
@octopus-community/react-native
React Native module for the Octopus Community Android and Swift SDKs.
Official documentation: Octopus Developer Guide — for concepts, SSO setup, and native SDK details.
Features
- SSO (Single Sign-On) — Connect your users with JWT from your backend; app-managed profile fields
- Theme customization — Colors, fonts, logo; light/dark and dual-mode support
- Display modes — Fullscreen via
openUI()or embedded via theOctopusUIViewcomponent (see API reference) - Reactive events — Unread notification count, community access state, and typed SDK events (content, interactions, gamification, navigation)
- Community access / A/B testing — Two cases: (1) Octopus manages the cohort: the SDK decides who has access; use
overrideCommunityAccessto override for testing andaddHasAccessToCommunityListenerto react to the state. (2) Your app manages access: your app decides who sees the community (e.g. your own feature flag); usetrackCommunityAccessto report the value to Octopus for analytics only (it does not change actual access). - Locale override — Set SDK UI language programmatically (
overrideDefaultLocale) - Custom analytics — Track custom events (
trackCustomEvent) - URL interception — Handle link taps in your app (
addNavigateToUrlListener)
Installation
npm install @octopus-community/react-nativeiOS setup
Make sure to use_frameworks in your Podfile.
# Podfile
linkage = :static # or :dynamic
if linkage != nil
Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
use_frameworks! :linkage => linkage.to_sym
endDue to a bug in XCode 15, you might need to set ENABLE_USER_SCRIPT_SANDBOXING to YES and then to NO in order to compile (see this issue).
Compatibility table
| React Native version(s) | Android | iOS | Old arch | New arch | Octopus native SDK | |-------------------------| ------- |-------| -------- | ------------- | ------------------- | | v0.81.x (tested 0.81.4) | 5.0+ | 14.0+ | ✅ | Interop layer | 1.9 |
- Older React Native versions (e.g. v0.78+) may work but are untested
- New architecture is supported via the React Native interoperability layer
- Other requirements:
- Android: Kotlin 2.x
- iOS: Xcode 16.0+
Expo
Configure use_frameworks (static or dynamic) with expo-build-properties:
[
"expo-build-properties",
{
"ios": {
"useFrameworks": "static"
}
}
]Usage
Initialization
Initialize the SDK with your API key with initialize.
Choose whether your app or Octopus handles user authentication:
Octopus-handled authentication
import { initialize } from '@octopus-community/react-native';
await initialize({
apiKey: 'YOUR_OCTOPUS_API_KEY',
connectionMode: { type: 'octopus' }
});Single Sign-On (SSO)
For SSO mode:
- your app manages user authentication and certain profile fields; you specify which profile fields your app will handle directly
- you must provide a token provider that returns a valid JWT for the connected user. The JWT must be signed on your backend using the secret key provided by Octopus — never embed the secret in the app. See Generate a signed JWT for SSO
- in React components, use the
useUserTokenProviderhook to supply the token:
import {
initialize,
addEditUserListener,
addLoginRequiredListener,
connectUser,
disconnectUser,
useUserTokenProvider,
closeUI,
} from '@octopus-community/react-native';
// Initialize with SSO mode and custom theme
await initialize({
apiKey: 'YOUR_OCTOPUS_API_KEY',
connectionMode: {
type: 'sso',
appManagedFields: ['username', 'profilePicture', 'biography']
},
theme: {
colors: {
primary: '#FF6B35', // Your brand's primary color
primaryLowContrast: '#FF8C69', // Lighter variation
primaryHighContrast: '#CC4A1A', // Darker variation
onPrimary: '#FFFFFF', // Text color on primary background
},
logo: {
image: Image.resolveAssetSource(require('./assets/images/logo.png')), // Your custom logo
},
}
});
// Listen for when authentication is required
const loginRequiredSubscription = addLoginRequiredListener(() => {
// Navigate to your app's login screen
console.log('User needs to log in');
closeUI();
});
// Listen for when users want to edit their profile
const editUserSubscription = addEditUserListener(({ fieldToEdit }) => {
// Navigate to your app's profile editing screen
// for the specific field (username, profilePicture, etc.)
console.log(`User wants to edit: ${fieldToEdit}`);
closeUI();
});
// Set up token provider (in a React component)
useUserTokenProvider(async () => {
const token = await refreshUserToken();
return token;
});
// Connect a user after they log in
await connectUser({
userId: 'unique-user-id',
profile: {
username: 'john_doe',
profilePicture: 'https://example.com/avatar.jpg',
biography: 'Software developer',
},
});
// Disconnect the user when they log out
await disconnectUser();
// Cleanup listeners when appropriate (eg. in return of a useEffect)
loginRequiredSubscription.remove();
editUserSubscription.remove();Show the UI
You can show the Octopus Community in two ways:
- Fullscreen — Call
openUI()to open the native Octopus home screen (modal-style). UsecloseUI()to dismiss it. - Embedded — Render the
OctopusUIViewcomponent inside your React tree for an in-screen embed. PassdisplayMode="embed"ordisplayMode="fullscreen"and optional theme/options. See the API reference and the example app for usage.
Theme Customization
The Octopus SDK provides comprehensive theming capabilities to match your app's branding. You can customize colors, fonts, and logo, with full support for both light and dark modes.
Basic Theme Setup
import { Image } from 'react-native';
await initialize({
apiKey: 'YOUR_OCTOPUS_API_KEY',
connectionMode: { type: 'octopus' },
theme: {
colors: {
primary: '#FF6B35', // Main brand color
primaryLowContrast: '#FF8C69', // Lighter variation of primary
primaryHighContrast: '#CC4A1A', // Darker variation for high contrast
onPrimary: '#FFFFFF', // Text color on primary background
},
logo: {
image: Image.resolveAssetSource(require('./assets/images/logo.png')),
},
}
});Dark/Light Mode Management
The SDK automatically handles system appearance changes, but you can also force specific modes:
System Mode (Default)
// The SDK automatically follows the system appearance
// No additional configuration needed
await initialize({
apiKey: 'YOUR_OCTOPUS_API_KEY',
connectionMode: { type: 'octopus' },
theme: { /* your theme */ }
});Forced Light Mode
import { Appearance } from 'react-native';
// Force light mode for your entire app
Appearance.setColorScheme('light');
await initialize({
apiKey: 'YOUR_OCTOPUS_API_KEY',
connectionMode: { type: 'octopus' },
theme: { /* your theme */ }
});Forced Dark Mode
import { Appearance } from 'react-native';
// Force dark mode for your entire app
Appearance.setColorScheme('dark');
await initialize({
apiKey: 'YOUR_OCTOPUS_API_KEY',
connectionMode: { type: 'octopus' },
theme: { /* your theme */ }
});Dual-Mode Color Themes
For enhanced theming, you can provide separate color sets for light and dark modes:
await initialize({
apiKey: 'YOUR_OCTOPUS_API_KEY',
connectionMode: { type: 'octopus' },
theme: {
colors: {
light: {
primary: '#3B82F6', // Blue for light mode
primaryLowContrast: '#60A5FA',
primaryHighContrast: '#1D4ED8',
onPrimary: '#FFFFFF',
},
dark: {
primary: '#60A5FA', // Lighter blue for dark mode
primaryLowContrast: '#93C5FD',
primaryHighContrast: '#3B82F6',
onPrimary: '#000000',
},
},
}
});Font Customization
Customize typography with text styles and font sizes:
await initialize({
apiKey: 'YOUR_OCTOPUS_API_KEY',
connectionMode: { type: 'octopus' },
theme: {
fonts: {
textStyles: {
title1: {
fontType: 'serif', // serif, monospace, or default
fontSize: { size: 28 }
},
title2: {
fontType: 'serif',
fontSize: { size: 22 }
},
body1: {
fontType: 'default', // Uses system default
fontSize: { size: 16 }
},
body2: {
fontSize: { size: 14 } // Only size, uses default font type
},
caption1: {
fontType: 'monospace',
fontSize: { size: 12 }
},
caption2: {
fontSize: { size: 10 }
},
}
}
}
});Theme Application
Themes are applied when the Octopus UI is opened. The SDK automatically detects the current system appearance (light/dark mode) and applies the appropriate theme configuration.
Complete Theme Example
Here's a comprehensive example showing all theming options:
import { Image, Appearance } from 'react-native';
import { initialize } from '@octopus-community/react-native';
// Force dark mode (optional)
Appearance.setColorScheme('dark');
await initialize({
apiKey: 'YOUR_OCTOPUS_API_KEY',
connectionMode: {
type: 'sso',
appManagedFields: ['username', 'profilePicture']
},
theme: {
// Dual-mode colors
colors: {
light: {
primary: '#8B5CF6',
primaryLowContrast: '#A78BFA',
primaryHighContrast: '#7C3AED',
onPrimary: '#FFFFFF',
},
dark: {
primary: '#A78BFA',
primaryLowContrast: '#C4B5FD',
primaryHighContrast: '#8B5CF6',
onPrimary: '#000000',
},
},
// Custom fonts
fonts: {
textStyles: {
title1: { fontType: 'serif', fontSize: { size: 28 } },
title2: { fontType: 'serif', fontSize: { size: 22 } },
body1: { fontSize: { size: 16 } },
body2: { fontSize: { size: 14 } },
caption1: { fontType: 'monospace', fontSize: { size: 12 } },
caption2: { fontSize: { size: 10 } },
}
},
// Custom logo
logo: {
image: Image.resolveAssetSource(require('./assets/images/logo.png')),
},
}
});Dynamic Theme Switching
To change themes in your app, you need to re-initialize the SDK with the new theme configuration:
// Example: Switch between different theme sets
const switchToGreenTheme = async () => {
await initialize({
apiKey: 'YOUR_OCTOPUS_API_KEY',
connectionMode: { type: 'sso', appManagedFields: ['username'] },
theme: {
colors: {
light: {
primary: '#10B981',
primaryLowContrast: '#34D399',
primaryHighContrast: '#059669',
onPrimary: '#FFFFFF',
},
dark: {
primary: '#34D399',
primaryLowContrast: '#6EE7B7',
primaryHighContrast: '#10B981',
onPrimary: '#000000',
},
}
}
});
};Theme Configuration Reference
Color Properties:
primary: Main brand color (hex format:#FF6B35orFF6B35)primaryLowContrast: Lighter variation for subtle elementsprimaryHighContrast: Darker variation for high contrast needsonPrimary: Text color displayed over primary background
Font Types:
default: System default fontserif: Serif font familymonospace: Monospace font family
Text Styles:
title1: Large titles (default: 28pt)title2: Medium titles (default: 22pt)body1: Primary body text (default: 16pt)body2: Secondary body text (default: 14pt)caption1: Small captions (default: 12pt)caption2: Extra small captions (default: 10pt)
Supported Formats:
- Colors: 3-digit (
#F63), 6-digit (#FF6633), 8-digit (#FF6633FF) hex codes - Images: Use
Image.resolveAssetSource(require('./path/to/image.png'))for bundled assets - Fonts: Choose between
serif,monospace, ordefaultfont types
Platform Behavior:
- iOS: Uses adaptive colors that automatically respond to system appearance changes
- Android: Theme is applied when the UI opens and reflects the current system appearance
- Theme Changes: Require re-initializing the SDK with new theme configuration
- System Mode: Automatically follows device light/dark mode settings
- Forced Mode: Use
Appearance.setColorScheme('light'|'dark')to override system settings
Note: All theme properties are optional. If not provided, the default Octopus theme will be used.
For more detailed theming information and advanced customization options, see the Octopus Community iOS SDK theming documentation.
API docs
For details about the Typescript API, head to the API docs.
Key Theming Functions
initialize(params): Initialize the SDK with theme configurationAppearance.setColorScheme(mode): Force light/dark mode (React Native API)openUI(): Open the Octopus UI with the current theme applied
Example app
The example app demonstrates the full SDK surface. From the root, run yarn example start then yarn example ios or yarn example android. It uses a tabbed UI:
| Tab | Purpose | |-----|---------| | Setup | Initialize the SDK (API key, SSO/Octopus mode), connect/disconnect user, display mode (fullscreen vs embed), locale override, URL interception toggle | | Community | Open the Octopus UI (fullscreen or embedded) with the current theme and options | | Theme | Theming: system/light/dark, color set, fonts, logo, bottom inset; see changes when reopening the UI | | SDK Data | Notifications count (refresh, listener), community access (override, track, listener), custom events, SDK event log |
See example/README.md for environment variables (API key, SSO user/token) and run instructions. The example is the best reference for implementing SSO, theming, reactive events, and URL interception in your app.
Troubleshooting
Any error that might be intercepted by the React Native module will be rejected in the methods you call. If it cannot be intercepted, you may see the underlying SDK's logs in your native logs.
Contributing
See the contributing guide to learn how to contribute to the repository and the development workflow.
