Quickstart
This guide will walk you through setting up the Expo Superwall SDK and displaying your first paywall.
Step 1: Wrap Your App with SuperwallProvider
The SuperwallProvider initializes the SDK with your API key. Wrap your app’s root component:
import { SuperwallProvider } from "expo-superwall" ;
export default function App () {
return (
< SuperwallProvider apiKeys = { { ios: "YOUR_SUPERWALL_API_KEY" /* android: API_KEY */ } } >
{ /* Your app content goes here */ }
</ SuperwallProvider >
);
}
Find your API key in your Superwall dashboard . You can provide separate keys for iOS and Android, or use the same key for both platforms.
Step 2: Handle Loading States
While the SDK initializes, show a loading indicator using the SuperwallLoading and SuperwallLoaded components:
import {
SuperwallProvider ,
SuperwallLoading ,
SuperwallLoaded ,
} from "expo-superwall" ;
import { ActivityIndicator , View , Text } from "react-native" ;
const API_KEY = "YOUR_SUPERWALL_API_KEY" ;
export default function App () {
return (
< SuperwallProvider apiKeys = { { ios: API_KEY } } >
< SuperwallLoading >
< ActivityIndicator style = { { flex: 1 } } />
</ SuperwallLoading >
< SuperwallLoaded >
< MainAppScreen />
</ SuperwallLoaded >
</ SuperwallProvider >
);
}
function MainAppScreen () {
return (
< View style = { { flex: 1 , alignItems: "center" , justifyContent: "center" } } >
< Text > Superwall SDK is ready! </ Text >
</ View >
);
}
Step 3: Identify Your User
Use the useUser hook to identify users when they log in:
import { useUser } from "expo-superwall" ;
import { Button , Text , View } from "react-native" ;
function UserManagementScreen () {
const { identify , user , signOut , subscriptionStatus } = useUser ();
const handleLogin = async () => {
// Identify the user with a unique ID
await identify ( `user_ ${ Date . now () } ` );
};
const handleSignOut = async () => {
await signOut ();
};
return (
< View style = { { padding: 20 } } >
< Text > Subscription Status: { subscriptionStatus ?. status ?? "unknown" } </ Text >
{ user && < Text > User ID: { user . appUserId } </ Text > }
< Button title = "Login" onPress = { handleLogin } />
< Button title = "Sign Out" onPress = { handleSignOut } />
</ View >
);
}
User identification is important for tracking subscription status and personalizing the paywall experience.
Step 4: Trigger a Paywall
Use the usePlacement hook to show paywalls at strategic points in your app:
import { usePlacement } from "expo-superwall" ;
import { Alert , Button , View } from "react-native" ;
function PaywallScreen () {
const { registerPlacement } = usePlacement ({
onError : ( err ) => console . error ( "Placement Error:" , err ),
onPresent : ( info ) => console . log ( "Paywall Presented:" , info ),
onDismiss : ( info , result ) =>
console . log ( "Paywall Dismissed:" , info , "Result:" , result ),
});
const handleTriggerPlacement = async () => {
await registerPlacement ({
placement: "your_placement_id" , // Replace with your actual placement ID
feature () {
// This function is called if the user is already subscribed
// or successfully subscribes through the paywall.
console . log ( "Feature unlocked!" );
Alert . alert ( "Feature Unlocked!" , "You can now access this feature." );
},
});
};
return (
< View style = { { padding: 20 } } >
< Button title = "Unlock Premium Feature" onPress = { handleTriggerPlacement } />
</ View >
);
}
Replace "your_placement_id" with an actual placement ID from your Superwall dashboard. Placements are configured remotely and determine when and how paywalls are shown.
Complete Example
Here’s a complete working example combining all the steps:
import {
SuperwallProvider ,
SuperwallLoading ,
SuperwallLoaded ,
useUser ,
usePlacement ,
} from "expo-superwall" ;
import { ActivityIndicator , Alert , Button , Text , View , StyleSheet } from "react-native" ;
const API_KEY = "YOUR_SUPERWALL_API_KEY" ;
export default function App () {
return (
< SuperwallProvider apiKeys = { { ios: API_KEY } } >
< SuperwallLoading >
< ActivityIndicator style = { { flex: 1 } } />
</ SuperwallLoading >
< SuperwallLoaded >
< MainAppScreen />
</ SuperwallLoaded >
</ SuperwallProvider >
);
}
function MainAppScreen () {
const { identify , user , subscriptionStatus } = useUser ();
const { registerPlacement } = usePlacement ({
onPresent : ( info ) => console . log ( "Paywall presented:" , info . name ),
onDismiss : ( info , result ) => console . log ( "Dismissed with:" , result ),
});
const handleLogin = async () => {
await identify ( `user_ ${ Date . now () } ` );
};
const handleShowPaywall = async () => {
await registerPlacement ({
placement: "campaign_trigger" ,
feature () {
Alert . alert ( "Success!" , "You now have access to premium features." );
},
});
};
return (
< View style = { styles . container } >
< Text style = { styles . title } > Expo Superwall SDK Demo </ Text >
< View style = { styles . section } >
< Text > Status: { subscriptionStatus ?. status ?? "unknown" } </ Text >
{ user && < Text > User: { user . appUserId } </ Text > }
</ View >
< View style = { styles . buttonContainer } >
< Button title = "Login" onPress = { handleLogin } />
< Button title = "Show Paywall" onPress = { handleShowPaywall } />
</ View >
</ View >
);
}
const styles = StyleSheet . create ({
container: {
flex: 1 ,
padding: 20 ,
justifyContent: "center" ,
},
title: {
fontSize: 24 ,
fontWeight: "bold" ,
marginBottom: 20 ,
textAlign: "center" ,
},
section: {
marginVertical: 20 ,
padding: 15 ,
backgroundColor: "#f5f5f5" ,
borderRadius: 8 ,
},
buttonContainer: {
gap: 10 ,
},
});
What’s Next?
You now have a working Superwall integration! Here are some next steps:
Update User Attributes Learn how to track custom user properties for targeting and personalization
Handle Events Set up event listeners to track paywall interactions and analytics
Error Handling Implement robust error handling for offline scenarios
Advanced Configuration Explore advanced SDK options and customization