Add authentication to React Native and Expo mobile applications using react-native-auth0.
auth0-quickstart skill firstauth0-expo skill for Expo apps with config pluginauth0-react skill for SPAs (Vite/CRA)auth0-nextjs for Next.js applicationsExpo:
bash
npx expo install react-native-auth0
React Native CLI:
bash
npm install react-native-auth0
npx pod-install # iOS only
For automated setup with Auth0 CLI, see Setup Guide for complete scripts.
For manual setup:
Create .env:
bash
AUTH0_DOMAIN=your-tenant.auth0.com
AUTH0_CLIENT_ID=your-client-id
iOS - Update ios/{YourApp}/Info.plist:
xml
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>None</string>
<key>CFBundleURLName</key>
<string>auth0</string>
<key>CFBundleURLSchemes</key>
<array>
<string>$(PRODUCT_BUNDLE_IDENTIFIER).auth0</string>
</array>
</dict>
</array>
Android - Update android/app/src/main/AndroidManifest.xml:
xml
<activity
android:name="com.auth0.android.provider.RedirectActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="YOUR_AUTH0_DOMAIN"
android:pathPrefix="/android/${applicationId}/callback"
android:scheme="${applicationId}" />
</intent-filter>
</activity>
Expo - Update app.json:
json
{
"expo": {
"scheme": "your-app-scheme",
"ios": {
"bundleIdentifier": "com.yourcompany.yourapp"
},
"android": {
"package": "com.yourcompany.yourapp"
}
}
}
Wrap your app with Auth0Provider:
typescript
import React from 'react';
import { Auth0Provider } from 'react-native-auth0';
import App from './App';
export default function Root() {
return (
<Auth0Provider
domain={process.env.AUTH0_DOMAIN}
clientId={process.env.AUTH0_CLIENT_ID}
>
<App />
</Auth0Provider>
);
}
typescript
import React from 'react';
import { View, Button, Text, ActivityIndicator } from 'react-native';
import { useAuth0 } from 'react-native-auth0';
export default function App() {
const { user, authorize, clearSession, isLoading } = useAuth0();
const login = async () => {
try {
await authorize({
scope: 'openid profile email'
});
} catch (error) {
console.error('Login error:', error);
}
};
const logout = async () => {
try {
await clearSession();
} catch (error) {
console.error('Logout error:', error);
}
};
if (isLoading) {
return <ActivityIndicator />;
}
return (
<View>
{user ? (
<>
<Text>Welcome, {user.name}!</Text>
<Text>{user.email}</Text>
<Button title="Logout" onPress={logout} />
</>
) : (
<Button title="Login" onPress={login} />
)}
</View>
);
}
Expo:
bash
npx expo start
React Native:
bash
npx react-native run-ios
# or
npx react-native run-android
MistakeFixForgot to wrap app with Auth0ProviderAll components using useAuth0() must be children of Auth0ProviderForgot to configure deep linkingAdd URL scheme to iOS Info.plist and Android AndroidManifest.xml (see Step 3)Callback URL mismatchEnsure callback URL in Auth0 Dashboard matches your app's URL scheme (e.g., com.yourapp.auth0://YOUR_DOMAIN/ios/com.yourapp/callback)iOS build fails after installRun npx pod-install to link native dependenciesApp created as SPA type in Auth0Must be Native application type for mobile appsNot handling auth errorsWrap authorize/clearSession calls in try-catch blocksDeep link not working on AndroidVerify android:exported="true" is set on RedirectActivity
auth0-quickstart - Basic Auth0 setupauth0-migration - Migrate from another auth providerauth0-mfa - Add Multi-Factor Authenticationauth0-cli - Manage Auth0 resources from the terminalCore Hook API:
useAuth0() - Main hook for authenticationauthorize() - Initiate loginclearSession() - Logoutuser - User profile objectgetCredentials() - Get tokens for API callsisLoading - Loading stateCommon Use Cases:
Auth0ProvidergetCredentials()