Get started with the React Native SDK
This guide installs the React Native SDK (@amplitude/analytics-react-native), initializes it, and sends one custom event to Amplitude. Each step lists the problems that commonly break that step, so you can fix each problem where it happens. For the full option list, go to Configuration options. For changes between versions, go to the React Native SDK release notes.
The React Native SDK is the analytics-only package. If you also need Session Replay, Feature Experiment, or Guides and Surveys, install the Unified SDK for React Native (@amplitude/unified-react-native) instead. It includes this SDK, so don't install both as direct dependencies.
Prerequisites
- An Amplitude project and its API key. Find the key in Settings > Projects > your project > General.
- The data center your organization uses: US (default) or EU.
- A React Native app for iOS, Android, or the web (react-native-web). React Native doesn't keep backward compatibility between releases, so check the React Native CLI compatibility list before you upgrade.
- React Native 0.68 or later, Gradle 7.5.1 or later, and Android Gradle Plugin 7.2.1 or later. These are the minimums SDK 1.4.0 and later build with. Amplitude support covers the latest React Native version only. For older SDK versions, go to Platform support.
- iOS 12.0 or later, and Android API level 21 or later. These are the minimums the SDK's native modules declare. Your React Native version can require higher ones.
Install the SDK
The SDK stores identity and unsent events in @react-native-async-storage/async-storage, so install that package too. To use a different storage backend, go to Store data somewhere other than AsyncStorage.
npm install @amplitude/analytics-react-native @react-native-async-storage/async-storage
cd ios && pod install
Then import the package:
import * as amplitude from "@amplitude/analytics-react-native";
The SDK has native modules for iOS and Android. If you ship over-the-air (OTA) updates, for example with Expo EAS Update, publish a new native build when you upgrade across a release that changed native code. Go to Platform support for those releases.
Fix installation problems
| Symptom | Cause | Fix |
|---|---|---|
Events have no os_name, device_model, or carrier, and platform is Web on a phone | The SDK's native module isn't linked, so the SDK falls back to web context. | Run pod install, rebuild the app, and use a development build instead of Expo Go. |
| Android build fails after you add the SDK | Gradle or the Android Gradle Plugin is older than the SDK supports. | Upgrade to Gradle 7.5.1 or later and Android Gradle Plugin 7.2.1 or later. |
| Native behavior differs between builds that ship the same JavaScript | An OTA update changed the SDK's JavaScript without the native code from the same release. | Publish a new native build. Go to Platform support. |
Initialize the SDK
Call init() once, as early as possible, for example at the top of your app's entry file. The SDK queues calls you make before init() finishes and runs them in order afterward.
amplitude.init("AMPLITUDE_API_KEY");
Pass a user ID as the second argument when you already know it. Pass options as the third argument. To pass options without a user ID, set the second argument to undefined:
amplitude.init("AMPLITUDE_API_KEY", "user-12345", {
autocapture: true,
});
amplitude.init("AMPLITUDE_API_KEY", undefined, {
autocapture: true,
});
If your project uses the EU data center, set serverZone:
amplitude.init("AMPLITUDE_API_KEY", undefined, {
serverZone: "EU",
});
Autocapture is off by default. autocapture: true turns on sessions, application lifecycles, screen views, element interactions, frustration interactions, and network tracking. For each feature, go to Autocapture.
Fix initialization problems
| Symptom | Cause | Fix |
|---|---|---|
Options seem ignored, and user_id on events is an object such as {"serverZone":"EU"} | You passed options as the second argument. The second argument is the user ID. | Pass options third: init(apiKey, undefined, options). |
Events go to the wrong region, or ingestion returns Invalid API key | serverZone doesn't match the project's data center. | Set serverZone: "EU" for EU projects. Omit it for US projects. |
| A new device ID on every app launch, and unsent events lost on restart | AsyncStorage isn't installed or linked. The SDK doesn't throw. It keeps identity and the event queue in memory instead. | Install @react-native-async-storage/async-storage, run pod install, and rebuild the app. Or pass your own cookieStorage and storageProvider. |
Log warning: Network connectivity checker plugin found no connectivity source; defaulting to online. | The SDK's connectivity native module isn't linked, so the SDK can't detect offline periods. | Rebuild the app after pod install. Without the module, the SDK still sends events but doesn't pause uploads offline. |
Send a first event
Track one custom event and wait for the upload result. track() returns an object whose promise resolves after the SDK finishes the upload attempt.
const result = await amplitude.track("Sign Up Clicked", {
plan: "starter",
}).promise;
console.log(result.code, result.message);
// 200 "Event tracked successfully"
The SDK uploads queued events about one second after the first one enters the queue, in requests of up to 30 events, so expect about one second of delay.
Fix upload problems
result.code and result.message | Cause | Fix |
|---|---|---|
0, Event skipped due to optOut config | Opt-out is on for this device. The SDK stores opt-out with identity, so it persists across app launches. | Call amplitude.setOptOut(false). |
0, Event skipped due to empty event type | The event name is empty. | Pass a non-empty string as the first argument. |
400, Event rejected due to missing API key | init() received an empty API key. | Check the variable that holds your key. A missing environment variable often becomes an empty string at build time. |
400, Invalid API key: ... | The key is wrong, or belongs to a project in the other data center. | Copy the key again and check serverZone. |
500, Event rejected due to exceeded retry count | The request never succeeded, and the SDK gave up after flushMaxRetries (5) attempts. No network, a blocked host, or server errors cause this. | Check the device's connection and any proxy or firewall between the device and api2.amplitude.com (or api.eu.amplitude.com). Go to Verify events. |
| The promise never resolves | init() never ran on this instance, or the device is offline and the SDK is holding the event until it reconnects. | Make sure init() runs on the same instance. Check connectivity. |
Confirm the event in Amplitude
- In Amplitude, open User Lookup and search for the user ID you passed, or for the device ID from
amplitude.getDeviceId(). - Open the Activity tab and turn on Live event updates.
- Confirm that
Sign Up Clickedappears with theplanproperty.
If the event doesn't appear within a minute, follow Verify events. That page walks through each stage between track() and Amplitude's servers.
Next steps
- Identify signed-in users with
setUserId(), and callreset()when they sign out. - Track screens with React Navigation.
- Choose which Autocapture events to turn on.
- Add the custom events and properties your tracking plan needs. Go to Track events.
Was this helpful?
For AI agents: a documentation index is available at /docs/llms.txt. Append .md to any page URL for markdown, or send Accept: text/markdown.