|
| 1 | +# Klaviyo React Native SDK Example App |
| 2 | + |
| 3 | +This example app demonstrates the full API surface of the Klaviyo React Native SDK, including profile management, event tracking, in-app forms, geofencing, and push notifications. |
| 4 | + |
| 5 | +## Getting Started |
| 6 | + |
| 7 | +### 1. Configure Your API Key |
| 8 | + |
| 9 | +The app loads your Klaviyo public API key from a gitignored `.env` file via |
| 10 | +[`react-native-dotenv`](https://github.com/goatandsheep/react-native-dotenv). |
| 11 | + |
| 12 | +1. Copy the template: `cp .env.template .env` |
| 13 | +2. Edit `.env` and set `KLAVIYO_API_KEY=` to your actual public API key |
| 14 | +3. Restart Metro with `yarn start --reset-cache` so the babel plugin picks up the new value |
| 15 | + |
| 16 | +> **If you hit "Klaviyo API key not configured" after setting up `.env`:** Metro inlines |
| 17 | +> `.env` values at bundle time via `react-native-dotenv`. If Metro was already running when |
| 18 | +> you created or edited `.env`, it will serve a cached bundle with `KLAVIYO_API_KEY` still |
| 19 | +> undefined. Stop Metro and restart it with `yarn start --reset-cache` (from `example/`). |
| 20 | +
|
| 21 | +Notes: |
| 22 | + |
| 23 | +- `.env` is gitignored — only `.env.template` is checked in. |
| 24 | +- Without a `.env` file the app still builds and runs; it shows a friendly warning |
| 25 | + banner and the non-push features (profile, events, in-app forms, geofencing) |
| 26 | + continue to work without a key. |
| 27 | + |
| 28 | +### 2. Install Dependencies |
| 29 | + |
| 30 | +```bash |
| 31 | +yarn install |
| 32 | +cd ios && pod install && cd .. |
| 33 | +``` |
| 34 | + |
| 35 | +### 3. Run the App |
| 36 | + |
| 37 | +```bash |
| 38 | +# Start Metro bundler |
| 39 | +yarn start |
| 40 | + |
| 41 | +# Run iOS |
| 42 | +yarn ios |
| 43 | + |
| 44 | +# Run Android |
| 45 | +yarn android |
| 46 | +``` |
| 47 | + |
| 48 | +## Push Notifications |
| 49 | + |
| 50 | +**Push is disabled by default.** The example app launches without any Firebase |
| 51 | +configuration — the rest of the demo (profile management, events, in-app forms, |
| 52 | +geofencing) still works, and the Push Notifications section just shows setup |
| 53 | +instructions until you wire Firebase up. |
| 54 | + |
| 55 | +Push notifications are handled via `@react-native-firebase/messaging` in the |
| 56 | +JavaScript layer. This is the recommended approach for React Native apps — the |
| 57 | +SDK is initialized from JS, and Firebase manages push tokens cross-platform. |
| 58 | + |
| 59 | +### Firebase Setup |
| 60 | + |
| 61 | +To enable push notifications, add your Firebase configuration files: |
| 62 | + |
| 63 | +**iOS:** |
| 64 | + |
| 65 | +1. Add `GoogleService-Info.plist` to `example/ios/KlaviyoReactNativeSdkExample/` |
| 66 | +2. Run `pod install` from the `example/ios/` directory |
| 67 | + |
| 68 | +**Android:** |
| 69 | + |
| 70 | +1. Replace `example/android/app/google-services.json.template` with a real |
| 71 | + `google-services.json` from your Firebase project. |
| 72 | + - The template is a placeholder structure checked into the repo so that the |
| 73 | + Android build succeeds without real Firebase config. It lets the app run |
| 74 | + (with push simply disabled) on a cold clone. Replace it with a real |
| 75 | + `google-services.json` to enable push on Android. |
| 76 | + - `google-services.json` itself is gitignored — only the template is checked in. |
| 77 | +2. Ensure `applicationId` in `build.gradle` matches your Firebase project. |
| 78 | + |
| 79 | +The app automatically detects Firebase and enables push features once the config |
| 80 | +files are in place. |
| 81 | + |
| 82 | +### Native Push (Alternative) |
| 83 | + |
| 84 | +For apps that prefer to handle push tokens natively (e.g., brownfield apps), the native code in `AppDelegate.mm` and `MainApplication.kt` contains commented-out reference implementations. See those files for details. |
| 85 | + |
| 86 | +Note: `Klaviyo.handlePush(intent)` in `MainActivity.kt` is always required on Android — push open tracking depends on native intent handling regardless of how tokens are managed. |
| 87 | + |
| 88 | +## Integration Step Comments |
| 89 | + |
| 90 | +The example source is annotated with `JS Installation Step`, `iOS Installation Step`, |
| 91 | +and `Android Installation Step` comments that mark the code an integrator needs to |
| 92 | +replicate in their own app. Grep for any of those prefixes across `example/` to walk |
| 93 | +the integration surface: |
| 94 | + |
| 95 | +- `JS Installation Step` — `example/src/App.tsx` and `example/index.js` (SDK init, |
| 96 | + API key sourcing, optional `@react-native-firebase/messaging` background handler) |
| 97 | +- `iOS Installation Step` — `example/ios/KlaviyoReactNativeSdkExample/AppDelegate.{h,mm}`, |
| 98 | + `PushNotificationsHelper.swift`, `NotificationService.swift`, and the Podfile |
| 99 | +- `Android Installation Step` — `example/android/build.gradle`, `app/build.gradle`, |
| 100 | + `AndroidManifest.xml`, and `MainActivity.kt` |
| 101 | + |
| 102 | +The numbering is descriptive, not strict: some numbers are skipped where the |
| 103 | +corresponding step now lives in JS (e.g., SDK init, push permission request), and |
| 104 | +some steps are labelled by concern rather than number (e.g., "Firebase, part 1 of 2") |
| 105 | +where a numbered slot didn't fit the flow. |
| 106 | + |
| 107 | +## Features Demonstrated |
| 108 | + |
| 109 | +- **Profile Management** — Set email, phone, external ID individually or together; reset profile |
| 110 | +- **Event Tracking** — Create test events and Viewed Product events |
| 111 | +- **In-App Forms** — Register/unregister with configurable session timeout |
| 112 | +- **Geofencing** — Location permission flow, register/unregister, list current geofences |
| 113 | +- **Push Notifications** — Firebase-based permission request, token display, badge count (iOS) |
| 114 | +- **Deep Linking** — Universal tracking link handling via `Linking` API |
0 commit comments