Overview
SuperwallError is a component that renders its children only when Superwall configuration has failed. Use this component to display an error message or fallback UI when the Superwall SDK fails to initialize.
The component supports both static error UI and dynamic error rendering using a render function that receives the error message.
This component is essential for handling offline scenarios and other configuration failures gracefully.
Props
children
ReactNode | (error: string) => ReactNode
required
The content to render when Superwall has a configuration error. Can be either:
- Static React nodes: Displays the same UI regardless of the error
- Render function: Receives the error message string and returns custom UI
Basic Usage
Static Error UI
import { SuperwallProvider, SuperwallError } from "expo-superwall";
import { View, Text } from "react-native";
export default function App() {
return (
<SuperwallProvider apiKeys={{ ios: "YOUR_API_KEY" }}>
<SuperwallError>
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text style={{ fontSize: 18 }}>Failed to load Superwall</Text>
</View>
</SuperwallError>
{/* Rest of your app */}
</SuperwallProvider>
);
}
Dynamic Error UI with Error Message
import { SuperwallProvider, SuperwallError } from "expo-superwall";
import { View, Text, Button } from "react-native";
export default function App() {
return (
<SuperwallProvider apiKeys={{ ios: "YOUR_API_KEY" }}>
<SuperwallError>
{(error) => (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text style={{ fontSize: 18, marginBottom: 10 }}>
Failed to initialize Superwall
</Text>
<Text style={{ color: "gray", marginBottom: 20 }}>
{error}
</Text>
<Button
title="Retry"
onPress={() => {
// Implement retry logic
// e.g., reload the app or reconfigure
}}
/>
</View>
)}
</SuperwallError>
{/* Rest of your app */}
</SuperwallProvider>
);
}
Complete State Management
Handle all SDK states with loading, loaded, and error components:
import {
SuperwallProvider,
SuperwallLoading,
SuperwallLoaded,
SuperwallError,
} from "expo-superwall";
import { ActivityIndicator, View, Text, Button } from "react-native";
const API_KEY = "YOUR_SUPERWALL_API_KEY";
export default function App() {
return (
<SuperwallProvider apiKeys={{ ios: API_KEY }}>
{/* Show while loading */}
<SuperwallLoading>
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<ActivityIndicator size="large" />
<Text style={{ marginTop: 16 }}>Initializing...</Text>
</View>
</SuperwallLoading>
{/* Show if configuration fails */}
<SuperwallError>
{(error) => (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center", padding: 20 }}>
<Text style={{ fontSize: 20, fontWeight: "bold", marginBottom: 10 }}>
Configuration Error
</Text>
<Text style={{ color: "gray", marginBottom: 20, textAlign: "center" }}>
{error}
</Text>
<Button
title="Try Again"
onPress={() => {
// Reload app or implement retry logic
}}
/>
</View>
)}
</SuperwallError>
{/* Show when ready */}
<SuperwallLoaded>
<MainAppScreen />
</SuperwallLoaded>
</SuperwallProvider>
);
}
function MainAppScreen() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>App is ready!</Text>
</View>
);
}
With Error Tracking
Combine with the onConfigurationError callback for comprehensive error handling:
import {
SuperwallProvider,
SuperwallLoading,
SuperwallLoaded,
SuperwallError,
} from "expo-superwall";
import { View, Text, Button } from "react-native";
export default function App() {
return (
<SuperwallProvider
apiKeys={{ ios: "YOUR_API_KEY" }}
onConfigurationError={(error) => {
// Log to error tracking service
console.error("Superwall config failed:", error);
// Example: Send to Sentry
// Sentry.captureException(error);
// Example: Track in analytics
// analytics.track("superwall_config_error", {
// error: error.message,
// timestamp: Date.now()
// });
}}
>
<SuperwallLoading>
<LoadingScreen />
</SuperwallLoading>
<SuperwallError>
{(error) => (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center", padding: 20 }}>
<Text style={{ fontSize: 18, marginBottom: 10 }}>
Unable to Connect
</Text>
<Text style={{ color: "gray", marginBottom: 20, textAlign: "center" }}>
Please check your internet connection and try again.
</Text>
<Text style={{ fontSize: 12, color: "#ccc", marginBottom: 20 }}>
Error: {error}
</Text>
<Button title="Retry" onPress={() => {/* retry */}} />
</View>
)}
</SuperwallError>
<SuperwallLoaded>
<YourApp />
</SuperwallLoaded>
</SuperwallProvider>
);
}
Behavior
When It Renders
The component renders children when:
- SDK configuration has failed (
configurationError !== null)
When It Hides
The component renders null when:
- SDK is successfully configured
- SDK is still loading
- No error has occurred
Common Error Scenarios
Network Errors
<SuperwallError>
{(error) => {
const isNetworkError = error.includes("network") || error.includes("timeout");
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text style={{ fontSize: 18, marginBottom: 10 }}>
{isNetworkError ? "Connection Error" : "Configuration Error"}
</Text>
<Text style={{ color: "gray", marginBottom: 20 }}>
{isNetworkError
? "Please check your internet connection"
: error
}
</Text>
<Button title="Retry" onPress={handleRetry} />
</View>
);
}}
</SuperwallError>
Invalid API Key
<SuperwallError>
{(error) => {
const isInvalidKey = error.includes("API key") || error.includes("unauthorized");
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text style={{ fontSize: 18, marginBottom: 10 }}>
{isInvalidKey ? "Invalid Configuration" : "Error"}
</Text>
<Text style={{ color: "gray" }}>
{isInvalidKey
? "Please check your Superwall API key"
: error
}
</Text>
</View>
);
}}
</SuperwallError>
Implementation Details
The component uses the useSuperwall hook to access the error state:
const error = useSuperwall((state) => state.configurationError);
if (!error) {
return null;
}
return typeof children === "function" ? children(error) : children;
Best Practices
Always Provide User-Friendly Error Messages
// ✅ Good: User-friendly message
<SuperwallError>
{(error) => (
<View>
<Text>We're having trouble connecting</Text>
<Text style={{ fontSize: 12 }}>{error}</Text>
</View>
)}
</SuperwallError>
// ❌ Avoid: Just showing raw error
<SuperwallError>
{(error) => <Text>{error}</Text>}
</SuperwallError>
Provide Retry Mechanism
<SuperwallError>
{(error) => (
<View>
<Text>Configuration failed</Text>
<Button
title="Try Again"
onPress={() => {
// Implement retry logic
}}
/>
</View>
)}
</SuperwallError>
Log Errors for Debugging
Combine UI error handling with error tracking:
<SuperwallProvider
apiKeys={{ ios: "YOUR_API_KEY" }}
onConfigurationError={(error) => {
console.error("Config error:", error);
// Log to your error tracking service
}}
>
<SuperwallError>
{(error) => <ErrorUI error={error} />}
</SuperwallError>
</SuperwallProvider>
The SDK will gracefully handle offline scenarios and configuration failures, ensuring your app doesn’t hang indefinitely in a loading state.
Error State Access
You can also access the error state programmatically using useSuperwall:
import { useSuperwall } from "expo-superwall";
function ErrorHandler() {
const configError = useSuperwall((state) => state.configurationError);
if (configError) {
return (
<View>
<Text>Configuration Error: {configError}</Text>
</View>
);
}
return null;
}
See Also