Your resource for web content, online publishing
and the distribution of digital products.
«  
  »
S M T W T F S
 
 
 
 
 
 
1
 
2
 
3
 
4
 
5
 
6
 
7
 
8
 
9
 
 
 
 
 
 
 
 
 
18
 
19
 
20
 
21
 
22
 
23
 
24
 
25
 
26
 
27
 
28
 
29
 
30
 
31
 
 
 
 
 
 

Setting Up Auth0 Authentication with Expo Router: A Complete Guide

DATE POSTED:March 16, 2025

Implementing a robust authentication system is crucial for mobile applications. In this guide, I'll walk you through setting up Auth0 authentication with Expo Router, creating a seamless and secure user experience.

\

Prerequisites

Before starting, ensure you have:

  • An Expo project using Expo Router
  • An Auth0 account with a configured application
  • Basic understanding of React Native and TypeScript
  • \
Step 1: Install Required Dependencies

First, install the Auth0 React Native SDK:

yarn add react-native-auth0

\

Step 2: Configure Auth0

Create an auth0.config.js file in your project root:

const config = { clientId: "YOUR_AUTH0_CLIENT_ID", domain: "YOUR_AUTH0_DOMAIN", } export default config

Replace the placeholders with your actual Auth0 credentials.

\

Step 3: Create an Authentication Context

The authentication context will manage the auth state throughout your app. Create a file called useAuth.tsx in your hooks directory:

import { createContext, useContext, useEffect, useState } from "react" import { useAuth0 } from "react-native-auth0" import { router, useSegments, useRootNavigationState } from "expo-router" // Define the shape of our auth context type AuthContextType = { signIn: () => Promise signOut: () => Promise isAuthenticated: boolean isLoading: boolean user: any error: Error | null } // Create the context with a default value const AuthContext = createContext(null) // Provider component that wraps the app export function AuthProvider({ children }: { children: React.ReactNode }) { const { authorize, clearSession, user, error, getCredentials, isLoading } = useAuth0() const [isAuthenticated, setIsAuthenticated] = useState(false) const segments = useSegments() const navigationState = useRootNavigationState() // Check if the user is authenticated and redirect accordingly useEffect(() => { if (!navigationState?.key) return const inAuthGroup = segments[0] === "(auth)" if (isAuthenticated && inAuthGroup) { // Redirect authenticated users from auth screens to the main app router.replace("/(tabs)") } else if (!isAuthenticated && !inAuthGroup) { // Redirect unauthenticated users to the login screen router.replace("/(auth)/login") } }, [isAuthenticated, segments, navigationState?.key]) // Update authentication state when user changes useEffect(() => { setIsAuthenticated(!!user) }, [user]) // Sign in function const signIn = async () => { try { await authorize() const credentials = await getCredentials() console.log("Auth credentials:", credentials) setIsAuthenticated(true) } catch (e) { console.error("Login error:", e) } } // Sign out function const signOut = async () => { try { await clearSession() setIsAuthenticated(false) } catch (e) { console.error("Logout error:", e) } } return ( {children} ) } // Custom hook to use the auth context export function useAuth() { const context = useContext(AuthContext) if (!context) { throw new Error("useAuth must be used within an AuthProvider") } return context }

This context provides:

  • Authentication state management
  • Sign-in and sign-out functions
  • Automatic redirection based on authentication status
  • Access to user information and error states

\

Step 4: Set Up the Root Layout

Update your app/_layout.tsx file to include the Auth0Provider and AuthProvider:

import { Auth0Provider } from "react-native-auth0" import config from "@/auth0.config" import { AuthProvider } from "@/hooks/useAuth" // Other imports... export default function RootLayout() { // Other code... return ( ) }

\

Step 5: Create the Authentication Group

Expo Router uses directory-based routing. Create an (auth) directory in your app folder with a layout file:

// app/(auth)/_layout.tsx import { Stack } from "expo-router" export default function AuthLayout() { return ( ) }

\

Step 6: Create the Login Screen

Create a login screen in app/(auth)/login.tsx:

import { ThemedText } from "@/components/ThemedText" import { useAuth } from "@/hooks/useAuth" import { StyleSheet, View, TouchableOpacity, ActivityIndicator, } from "react-native" export default function LoginScreen() { const { signIn, isLoading, error } = useAuth() return ( Welcome to Your App Sign in to continue {isLoading ? ( ) : ( Sign In )} {error && ( {error.message} )} ) } // Styles...

\

Step 7: Create a Profile Screen

Add a profile screen to display user information and provide a logout option:

// app/(tabs)/profile.tsx import { ThemedText } from "@/components/ThemedText" import { useAuth } from "@/hooks/useAuth" import { StyleSheet, View, TouchableOpacity, Image, ScrollView, } from "react-native" export default function ProfileScreen() { const { user, signOut, isLoading } = useAuth() return ( {user?.picture ? ( ) : ( {user?.name?.charAt(0) || user?.email?.charAt(0) || "?"} )} {user?.name || "User"} {user?.email || ""} {/* User information display */} Sign Out ) } // Styles...

\

Step 8: Update the Tabs Layout

Ensure your tabs layout includes the profile tab and checks authentication:

// app/(tabs)/_layout.tsx import { useAuth } from "@/hooks/useAuth" // Other imports... export default function TabLayout() { const { isAuthenticated } = useAuth() // Redirect to login if not authenticated React.useEffect(() => { if (!isAuthenticated) { // The AuthProvider will handle the redirect } }, [isAuthenticated]) return ( {/* Other tabs */} ( ), }} /> ) }

\

Step 9: Create a Root Redirect

Finally, create a root index file to handle initial routing:

// app/index.tsx import { Redirect } from "expo-router" import { useAuth } from "@/hooks/useAuth" export default function Index() { const { isAuthenticated, isLoading } = useAuth() // While checking authentication status, don't redirect yet if (isLoading) { return null } // Redirect based on authentication status return isAuthenticated ? ( ) : ( ) }

\

How It Works
  1. Initial Load: When the app starts, it checks the authentication status.
  2. Authentication Flow:
  • Unauthenticated users are directed to the login screen
  • After successful login, users are redirected to the main app
  • The profile screen displays user information and provides logout functionality
  1. Protected Routes: The AuthProvider automatically protects routes by redirecting unauthenticated users to the login screen.

\

Benefits of This Approach
  • Clean Separation: Authentication logic is isolated in a dedicated context
  • Route Protection: Automatic redirection based on authentication status
  • Reusable Authentication: The useAuth hook can be used throughout the app
  • Seamless UX: Users are directed to the appropriate screens based on their authentication status

\

Conclusion

Setting up Auth0 with Expo Router provides a robust authentication system for your mobile application. This approach leverages Expo Router's group-based routing to create a clean separation between authenticated and unauthenticated content, while the authentication context manages the state and provides a consistent interface for authentication operations.

By following this guide, you've implemented a complete authentication flow that handles login, logout, and protected routes in a maintainable and scalable way.