Skip to content

Commit e3ae348

Browse files
evan-masseauclaude
andcommitted
feat(example): rebuild app with sectioned UI, JS-first init, API coverage
Replace the legacy button-wall demo with an interactive, sectioned example that covers the full Klaviyo SDK public API surface and initializes the SDK from JavaScript instead of native code. - App.tsx: SectionList layout with Profile / Events / Forms / Geofencing / Push / Deep Links sections - Profile section: External ID / Email / Phone inputs with individual set buttons, plus a collapsible "Additional Attributes" accordion for first/last name, title, organization and a "Location" accordion for city/country/zip/lat/long, aggregate Set Profile button, Reset Profile - Events: test event + Viewed Product, both with value + uniqueId + custom properties - Push: Firebase-backed permission request, Set Push Token, Set Badge Count (iOS-only, with number input) - Forms: explicit Register / Unregister - Geofencing: explicit Register / Unregister, Get Current Geofences modal - Deep link handling via Klaviyo.handleUniversalTrackingLink in a Linking useEffect with a proper cleanup - Env loading migrated to react-native-dotenv (.env + .env.example) with a typed @env declaration — no more try/require gymnastics - index.js registers a Firebase background message handler before AppRegistry as required by @react-native-firebase/messaging - Bumps @react-native-firebase/app and /messaging to ^24.0.0 for RN 0.81 bridgeless compatibility; adds react-native-dotenv dev dep - Drops legacy AppViewInterface, KlaviyoReactWrapper, RandomGenerators Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
1 parent 9023fb7 commit e3ae348

12 files changed

Lines changed: 1275 additions & 682 deletions

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ DerivedData
2929
*.xcuserstate
3030
project.xcworkspace
3131
.xcode.env.local
32-
GoogleService-info.plist
32+
GoogleService-Info.plist
3333

3434
# Android/IJ
3535
#
@@ -80,5 +80,8 @@ android/keystores/debug.keystore
8080
# generated by bob
8181
lib/
8282

83+
# Local environment config (API keys, etc.)
84+
example/.env
85+
8386
# Local AI settings files
8487
.claude

example/.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
KLAVIYO_API_KEY=YOUR_KLAVIYO_PUBLIC_API_KEY

example/babel.config.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,19 @@ const root = path.resolve(__dirname, '..');
77
module.exports = getConfig(
88
{
99
presets: ['module:@react-native/babel-preset'],
10+
plugins: [
11+
// allowUndefined: true so cold clones (no .env) build and show the friendly
12+
// warning UI rather than failing at Metro transform time. The runtime check
13+
// in App.tsx handles the missing-key case gracefully.
14+
[
15+
'module:react-native-dotenv',
16+
{
17+
moduleName: '@env',
18+
path: '.env',
19+
allowUndefined: true,
20+
},
21+
],
22+
],
1023
},
1124
{ root, pkg }
1225
);

example/index.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,18 @@ import { AppRegistry } from 'react-native';
22
import App from './src/App';
33
import { name as appName } from './app.json';
44

5+
// Register a background message handler BEFORE AppRegistry.registerComponent.
6+
// @react-native-firebase/messaging requires the handler to be attached
7+
// before the app mounts — otherwise iOS may suspend the process before the
8+
// handler is ready and the background push is dropped. The handler is a
9+
// no-op here; a real app would forward the payload to
10+
// Klaviyo.handleBackgroundMessage or similar.
11+
// The require is guarded so the app still runs when Firebase isn't linked.
12+
try {
13+
const messaging = require('@react-native-firebase/messaging').default;
14+
messaging().setBackgroundMessageHandler(async () => {});
15+
} catch {
16+
// Firebase not available — no-op.
17+
}
18+
519
AppRegistry.registerComponent(appName, () => App);

example/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
"build:ios": "react-native build-ios --scheme KlaviyoReactNativeSdkExample --mode Debug --extra-params \"-sdk iphonesimulator CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ GCC_OPTIMIZATION_LEVEL=0 GCC_PRECOMPILE_PREFIX_HEADER=YES ASSETCATALOG_COMPILER_OPTIMIZATION=time DEBUG_INFORMATION_FORMAT=dwarf COMPILER_INDEX_STORE_ENABLE=NO\""
1212
},
1313
"dependencies": {
14+
"@react-native-firebase/app": "^24.0.0",
15+
"@react-native-firebase/messaging": "^24.0.0",
1416
"@react-native/new-app-screen": "0.81.5",
1517
"react": "19.1.0",
1618
"react-native": "0.81.5",
@@ -27,7 +29,8 @@
2729
"@react-native/babel-preset": "0.81.5",
2830
"@react-native/metro-config": "0.81.5",
2931
"@react-native/typescript-config": "0.81.5",
30-
"react-native-builder-bob": "^0.36.0"
32+
"react-native-builder-bob": "^0.36.0",
33+
"react-native-dotenv": "^3.4.11"
3134
},
3235
"engines": {
3336
"node": ">=20"

0 commit comments

Comments
 (0)