Skip to content

๐Ÿ’ฐ Superwall

Dynamic paywall management for iOS and Android with remote configuration.

๐Ÿ’ก What is Superwall? Superwall is a paywall management platform that lets you design, test, and optimize subscription paywalls without releasing app updates. All paywall logic and UI are controlled remotely from the Superwall dashboard.

๐ŸŽฏ Architecture Overview

ExpoBase integrates Superwall using the official expo-superwall package with a declarative React Native approach. The integration separates business logic from paywall presentation - paywalls are managed dynamically from the Superwall dashboard, not coded in React Native.

Key Benefits

  • No-code paywall updates - Change designs and copy without app releases
  • A/B testing - Test different paywall variants to optimize conversions
  • Remote triggers - Control when paywalls appear based on user events
  • Native performance - Paywalls use native Apple Pay / Google Pay UI

๐Ÿ—๏ธ Technical Implementation

1. Provider Setup

The SuperwallProvider component wraps the entire application to make the SDK available everywhere. It initializes Superwall on app startup with API keys injected via environment variables.

File: context/SuperwallProvider.tsx

import React from 'react';
import { SuperwallProvider } from 'expo-superwall';
 
export default function Superwall({ children }: { children: React.ReactNode }) {
    return (
        <SuperwallProvider
            apiKeys={{
                ios: process.env.EXPO_PUBLIC_SUPERWALL_API_KEY_IOS ?? '',
                android: process.env.EXPO_PUBLIC_SUPERWALL_API_KEY_ANDROID ?? '',
            }}>
            {children}
        </SuperwallProvider>
    );
}

This provider wraps the app at the root level in app/_layout.tsx, right after the Authentication Context:

// Extract from app/_layout.tsx
<AuthProvider>
   <SuperwallProvider>
      <GestureHandlerRootView>
        <Stack ... />
      </GestureHandlerRootView>
   </SuperwallProvider>
</AuthProvider>

2. Native Configuration

For the native binaries (.ipa / .apk) to link the required native dependencies (C++/Swift SDK), the Expo plugin must be declared in app.json with expo-build-properties to ensure compatibility.

File: app.json

{
  "expo": {
    "plugins": [
      "expo-superwall",
      [
        "expo-build-properties",
        {
          "ios": {
            "deploymentTarget": "14.0",
            "useFrameworks": "static"
          },
          "android": {
            "minSdkVersion": 26
          }
        }
      ]
    ]
  }
}

โš ๏ธ Critical: The useFrameworks: "static" setting is essential for iOS compatibility with in-app purchase libraries.

3. Triggering Paywalls

Paywalls are triggered by events anywhere in the app using the useSuperwall hook. The app doesn't code the paywall design in React Native - it simply declares events, and Superwall's remote dashboard controls if/when a paywall appears.

Example: Triggering a paywall on a pricing screen

import { useSuperwall } from 'expo-superwall';
 
export default function PricingScreen() {
  const { superwall } = useSuperwall();
 
  const handleCheckout = () => {
    // Register event with Superwall
    // If the dashboard has a rule for 'campaign_trigger',
    // the native paywall will animate onto screen and handle Apple Pay / Google Pay
    superwall.registerEvent('campaign_trigger');
  };
 
  return (
    <Button onPress={handleCheckout}>
      Upgrade to Premium
    </Button>
  );
}
How it works:
  1. Developer calls superwall.registerEvent('event_name')
  2. Superwall SDK checks dashboard rules for this event
  3. If a paywall is configured for this event, it displays automatically
  4. Native payment UI (Apple Pay / Google Pay) handles the transaction
  5. Developer receives callback when purchase completes

๐Ÿ”‘ Setup Instructions

1. Create Superwall Account

  1. Go to superwall.com
  2. Create free account
  3. Create new project with your app name

2. Get API Keys

  1. In Superwall dashboard, go to Settings โ†’ API Keys
  2. Copy your iOS API key
  3. Copy your Android API key
  4. Add both to your .env.local:
# Superwall API Keys
EXPO_PUBLIC_SUPERWALL_API_KEY_IOS=pk_ios_xxxxxxxxxxxx
EXPO_PUBLIC_SUPERWALL_API_KEY_ANDROID=pk_android_xxxxxxxxxxxx

3. Configure Platforms

iOS Configuration

  1. In Superwall dashboard, go to Settings โ†’ Platforms
  2. Select iOS
  3. Enter your Bundle ID (from app.json)
  4. Connect to App Store Connect (for product IDs)
  5. Save configuration

Android Configuration

  1. In Superwall dashboard, go to Settings โ†’ Platforms
  2. Select Android
  3. Enter your Package Name (from app.json)
  4. Connect to Google Play Console (for product IDs)
  5. Save configuration

4. Create Your First Paywall

  1. Go to Paywalls in dashboard
  2. Click Create Paywall
  3. Choose a template or design from scratch
  4. Configure:
    • Title and description
    • Product offerings
    • Call-to-action buttons
    • Colors and branding
  5. Click Save

5. Create Event Triggers

  1. Go to Events in dashboard
  2. Click Create Event
  3. Enter event name (e.g., campaign_trigger, premium_feature_tap)
  4. Choose which paywall to show
  5. Configure presentation rules:
    • User segments
    • Frequency caps
    • A/B test variants
  6. Click Save

๐Ÿ’ป Usage Examples

Basic Paywall Trigger

import { useSuperwall } from 'expo-superwall';
 
function FeatureScreen() {
  const { superwall } = useSuperwall();
 
  const handlePremiumFeature = () => {
    superwall.registerEvent('premium_feature_tap');
  };
 
  return (
    <Button onPress={handlePremiumFeature}>
      Unlock Premium Feature
    </Button>
  );
}

Trigger with Custom Data

import { useSuperwall } from 'expo-superwall';
 
function ContentScreen({ contentId }: { contentId: string }) {
  const { superwall } = useSuperwall();
 
  const handleLockedContent = () => {
    superwall.registerEvent('locked_content_tap', {
      content_id: contentId,
      content_type: 'article',
    });
  };
 
  return (
    <Button onPress={handleLockedContent}>
      Read Full Article
    </Button>
  );
}

Check Subscription Status

import { useSuperwall } from 'expo-superwall';
 
function ProfileScreen() {
  const { superwall } = useSuperwall();
  const [isPremium, setIsPremium] = React.useState(false);
 
  React.useEffect(() => {
    superwall.getSubscriptionStatus().then(status => {
      setIsPremium(status === 'ACTIVE');
    });
  }, []);
 
  return (
    <View>
      <Text>Status: {isPremium ? 'Premium' : 'Free'}</Text>
    </View>
  );
}

๐ŸŽจ Best Practices

Event Naming

Use descriptive, action-based event names:

โœ… Good:

  • onboarding_completed
  • premium_feature_tap
  • settings_upgrade_button

โŒ Bad:

  • event1
  • click
  • button

Trigger Placement

Place events at natural conversion points:

  • After onboarding - User understands app value
  • Feature discovery - User tries to access premium feature
  • Limit reached - User hits free tier limit
  • Settings screen - User actively exploring premium

Testing

Always test paywalls in development:

# Build development version to test paywalls
npx expo run:ios
npx expo run:android

๐Ÿ’ก Pro Tip: Use Superwall's test mode to preview paywalls without making real purchases during development.


๐Ÿ” Troubleshooting

Paywall Not Showing

  1. Check event registration - Verify event name matches dashboard exactly
  2. Check targeting rules - Ensure you match the audience segment
  3. Check frequency caps - You may have already seen the paywall
  4. Check API keys - Verify keys are correct for the platform

API Key Issues

  1. Verify keys are set in .env.local
  2. Restart development server after changing keys
  3. Rebuild app if keys were added after initial build
  4. Check keys match your Superwall project

Products Not Loading

  1. Ensure products are configured in App Store Connect / Google Play
  2. Verify product IDs match in Superwall dashboard
  3. Check platform configuration in Superwall settings
  4. Wait for product sync (can take a few minutes)

Build Errors

If you get native build errors:

# Clean and rebuild
npx expo prebuild --clean

Ensure expo-build-properties is configured correctly in app.json (see Native Configuration section).


๐Ÿ“Š Analytics & Optimization

Superwall automatically tracks:

  • Impressions - How many times paywalls are shown
  • Conversions - How many users subscribe
  • Revenue - Total subscription revenue
  • Variants - A/B test performance

Access analytics in the Superwall dashboard under Analytics.

A/B Testing

  1. Create multiple paywall variants
  2. Assign variants to the same event
  3. Set traffic split (e.g., 50/50)
  4. Monitor conversion rates
  5. Choose winning variant

๐ŸŽฏ Summary

In ExpoBase, Superwall integration follows these principles:

  1. API keys stored in .env.local
  2. SuperwallProvider boots SDK at launch
  3. expo-superwall linked via Expo plugin with static frameworks
  4. Developers trigger events like registerEvent('premium_click')
  5. Superwall dashboard controls when/how paywalls appear

This architecture separates presentation from logic - you control the triggers in code, Superwall controls the UI remotely.


๐ŸŽฏ Next Step

Continue to ๐Ÿ“Š Revenue Cat to set up subscription management.


Step 5/12 Complete โœ…

Superwall paywalls configured for iOS & Android!

๐Ÿ“š Additional Resources

Official Documentation