Quickstart Adapty setup guide: React Native with Expo

Ben Gohlke
Ben Gohlke
7 min read
Quickstart Adapty setup guide: React Native with Expo

Get from zero Adapty setup to displaying a paywall and processing purchases in under 60 minutes using Expo and React Native.

Prerequisites

  • You have a working React Native app (built with Expo)
  • You’re using EAS Build and Dev Client (not Expo Go)
  • Your app includes at least one in-app purchase created in App Store Connect and synced in the Adapty dashboard
  • You’ve created an Adapty account and your app is added in the Adapty dashboard

Project Files

To follow along with the written, video, or LLM-based tutorial, download the project files from Github. The branch named starter contains the app without any Adapty integration. The main branch contains the finished project.

Install the Adapty SDK

Install the Adapty SDK and required helper:

npx expo install react-native-adapty tslib
Bash

Pre-build your Expo project

Because Adapty includes native code, you need to generate native iOS/Android directories:

npx expo prebuild
Bash

This will generate an ios and android folder, and a Podfile.

Add Adapty to your iOS project

Open the Podfile inside your ios/ directory and confirm Adapty was added. Then run:

cd ios
pod install
cd ..
Bash

You’ll also need to build a custom development client to run the app locally:

eas build --profile development --platform ios
Bash

Once built and installed, run the app using:

npx expo start --dev-client
Bash

Activate the SDK on app launch

Create AdaptyConstants.js to store keys and values you’ll use throughout the project:

export default {
  API_KEY: "your-public-sdk-key",
  ACCESS_LEVEL_ID: "premium",
  PLACEMENT_ID: "on_tap_history",
};
Bash

Create a new file called AdaptyService.js in your root directory and add:

import { adapty } from "react-native-adapty";
import AdaptyConstants from "./AdaptyConstants";

export const activationPromise = (async () => {
  try {
    await adapty.activate(AdaptyConstants.API_KEY);
  } catch (error) {
    console.error("Adapty activation failed:", error);
  }
})();
JavaScript

This exports a shared activation promise that will be awaited anywhere the SDK is used. It configures and activates the Adapty SDK. The Adapty UI library is built in, allowing you to display remotely configured paywalls with made with Paywall Builder.

Load the user’s subscription status

It’s important to have up-to-date information on the user’s subscription status. Adapty makes this easy with something called a user profile.

In ProfileContext.js, modify your context to include refreshing this profile. Here’s a version showing just the additions:

// Add the following imports
import { adapty } from "react-native-adapty";
import AdaptyConstants from "../AdaptyConstants";
import { activationPromise } from "../AdaptyService";

...

export function ProfileProvider({ children }) {
    ...

  // Add this useEffect() to get a fresh profile from Adapty
  useEffect(() => {
    let mounted = true;

    (async () => {
      try {
        await activationPromise;

        const profile = await adapty.getProfile();

        if (profile && profile.accessLevels) {
          const level = profile.accessLevels[AdaptyConstants.ACCESS_LEVEL_ID];
          if (mounted) {
            setIsPremium(
              !!(level?.isActive || level?.isInGracePeriod || level?.isLifetime)
            );
          }
        }
      } catch (error) {
        console.error("Error fetching Adapty profile:", error);
      }
    })();

    return () => {
      mounted = false;
    };
  }, []);

  ...
}
Bash

This code fetches an updated AdaptyProfile object from the SDK with the latest subscription and access level information. It then checks the access level and updates isPremium accordingly. You can use this within the app to determine whether to show premium content or functionality.

Show the Paywall

The next step is to present a paywall from Paywall Builder where applicable. In HomeScreen.js, when the user taps “View History”, we want to either navigate to the history screen (if they’re premium) or show a paywall using Adapty.

In the Home Screen, add these imports:

// Add these imports
import { adapty } from "react-native-adapty";
import { createPaywallView } from "react-native-adapty/dist/ui";
import AdaptyConstants from "../AdaptyConstants";
import { activationPromise } from "../AdaptyService";
Bash

Before we can show the Paywall Builder paywall, we need to fetch it from Adapty’s servers. We’ll do that and then create and present a paywall view based on that configuration.

export default function HomeScreen({ navigation }) {
    ...

    // Modify handleViewHistory to look like this:
  async function handleViewHistory() {
    await activationPromise;
    if (isPremium) {
      navigation.navigate("History");
    } else {
      try {
        const paywall = await adapty.getPaywall(
          AdaptyConstants.PLACEMENT_ID,
          "en"
        );
        if (paywall.hasViewConfiguration) {
          const view = await createPaywallView(paywall);
          view.registerEventHandlers({
            onCloseButtonPress() {
              return true;
            },
            onPurchaseCompleted(purchaseResult, product) {
              if (purchaseResult.type === "success") {
                purchasePremium(purchaseResult.profile);
                navigation.navigate("History");
                return true;
              }
              return false;
            },
            onPurchaseFailed(error) {
              console.error("Purchase failed:", error);
              return false;
            },
            onRestoreCompleted(restoredProfile) {
              purchasePremium(restoredProfile);
              navigation.navigate("History");
              return true;
            },
            onRestoreFailed(error) {
              console.error("Restore failed:", error);
              return false;
            },
            onRenderingFailed(error) {
              console.error("Error rendering paywall:", error);
              return false;
            },
          });
          await view.present();
        }
      } catch (error) {
        console.error("Error loading paywall:", error);
      }
    }
  }

  ...
}
Bash

The above block contains everything we need to display and manage the purchase process for a paywall. The various closures are used when success and failure states are triggered. They are your opportunity to take over control of the user experience and respond according to the outcome. The most common outcome is onPurchaseCompleted . In that case, we update the profile in our profile manager, and unlock premium content.

Congrats!

At this point, your app:

  • Initializes the Adapty SDK on launch
  • Loads a paywall dynamically from the Adapty dashboard
  • Supports purchasing and restoring subscriptions
  • Unlocks premium content using isPremium from your context

Related articles

Is the App Store revenue cut too high?
4 min read

Is the App Store revenue cut too high?

Days before WWDC 2020, we are taking a deep dive on the topic of Apple in-app purchases fees. Are they too high, or just right for the market?

Vitaly DavydovVitaly DavydovRead
How to add in-app subscriptions to an iOS app
7 min read

How to add in-app subscriptions to an iOS app

Learn how to add subscriptions for iOS in-app purchases with our comprehensive guide. Get started today and start monetizing your Apple app with in-app purchases!

Ben GohlkeBen GohlkeRead