AuthBoundary
A component that simplifies protecting routes and content based on authentication state. It handles four distinct scenarios: loading, error, unauthenticated, and authenticated.
Usage
import { AuthBoundary } from '@openfort/react-native';
import { Text, ActivityIndicator } from 'react-native';
function App() {
return (
<AuthBoundary
loading={<ActivityIndicator size="large" />}
unauthenticated={<LoginScreen />}
error={(error) => <Text>Error: {error.message}</Text>}
>
<AuthenticatedApp />
</AuthBoundary>
);
}Props
type AuthBoundaryProps = {
/** Component to render while the SDK is initializing */
loading: React.ReactNode
/** Component to render when the user is not authenticated */
unauthenticated: React.ReactNode
/** Optional component to render when there's an error during SDK initialization */
error?: React.ReactNode | ((error: Error) => React.ReactNode)
/** Children to render when the user is authenticated and the SDK is ready */
children: React.ReactNode
}States
The component handles four states:
| State | Condition | Renders |
|---|---|---|
| Loading | SDK is initializing | loading prop |
| Error | SDK encountered initialization error | error prop (if provided) |
| Unauthenticated | User is not logged in | unauthenticated prop |
| Authenticated | User is logged in, SDK is ready | children |
With React Navigation
A common pattern is to use AuthBoundary with React Navigation to show different navigation stacks based on authentication state:
import { AuthBoundary } from '@openfort/react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
const Stack = createNativeStackNavigator();
function App() {
return (
<NavigationContainer>
<AuthBoundary
loading={<SplashScreen />}
unauthenticated={
<Stack.Navigator>
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Signup" component={SignupScreen} />
</Stack.Navigator>
}
>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
</Stack.Navigator>
</AuthBoundary>
</NavigationContainer>
);
}With Expo Router
When using Expo Router, place the AuthBoundary in your root layout:
// app/_layout.tsx
import { AuthBoundary, OpenfortProvider } from '@openfort/react-native';
import { Slot } from 'expo-router';
import { ActivityIndicator, View } from 'react-native';
export default function RootLayout() {
return (
<OpenfortProvider
publishableKey="YOUR_PUBLISHABLE_KEY"
walletConfig={{
shieldPublishableKey: "YOUR_SHIELD_KEY",
createEncryptedSessionEndpoint: "https://your-backend.com/api/encryption-session"
}}
>
<AuthBoundary
loading={
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<ActivityIndicator size="large" />
</View>
}
unauthenticated={<LoginScreen />}
>
<Slot />
</AuthBoundary>
</OpenfortProvider>
);
}Error Handling
The error prop can be either a static component or a function that receives the error:
// Static error component
<AuthBoundary
loading={<LoadingScreen />}
unauthenticated={<LoginScreen />}
error={<Text>Something went wrong</Text>}
>
<App />
</AuthBoundary>
// Dynamic error component
<AuthBoundary
loading={<LoadingScreen />}
unauthenticated={<LoginScreen />}
error={(error) => (
<View>
<Text>Error: {error.message}</Text>
<Button title="Retry" onPress={() => { /* retry logic */ }} />
</View>
)}
>
<App />
</AuthBoundary>