1--- 2title: Authentication in Expo Router 3description: How to handle authentication when using Expo Router. 4--- 5 6import { FileTree } from '~/ui/components/FileTree'; 7 8It's common to restrict certain routes to users who are not authenticated. This can be achieved in a very organized way by using React Context and Route Groups. 9 10Consider the following project: 11 12<FileTree files={['app/_layout.js', 'app/index.js', 'app/(auth)/sign-in.js']} /> 13 14First, we'll setup a [React Context provider](https://reactjs.org/docs/context.html) that we can use to protect routes. This provider will use a mock implementation, you can replace it with your own [authentication provider](/guides/authentication/). 15 16```js title=context/auth.js 17import { useRouter, useSegments } from 'expo-router'; 18import React from 'react'; 19 20const AuthContext = React.createContext(null); 21 22// This hook can be used to access the user info. 23export function useAuth() { 24 return React.useContext(AuthContext); 25} 26 27// This hook will protect the route access based on user authentication. 28function useProtectedRoute(user) { 29 const segments = useSegments(); 30 const router = useRouter(); 31 32 React.useEffect(() => { 33 const inAuthGroup = segments[0] === '(auth)'; 34 35 if ( 36 // If the user is not signed in and the initial segment is not anything in the auth group. 37 !user && 38 !inAuthGroup 39 ) { 40 // Redirect to the sign-in page. 41 router.replace('/sign-in'); 42 } else if (user && inAuthGroup) { 43 // Redirect away from the sign-in page. 44 router.replace('/'); 45 } 46 }, [user, segments]); 47} 48 49export function Provider(props) { 50 const [user, setAuth] = React.useState(null); 51 52 useProtectedRoute(user); 53 54 return ( 55 <AuthContext.Provider 56 value={{ 57 signIn: () => setAuth({}), 58 signOut: () => setAuth(null), 59 user, 60 }}> 61 {props.children} 62 </AuthContext.Provider> 63 ); 64} 65``` 66 67Now we can use this context to control the access to the routes, we'll do this by using a Layout Route that wraps all the screens which require authentication. 68 69```js app/_layout.js 70import { Slot } from 'expo-router'; 71import { Provider } from '../context/auth'; 72 73export default function Root() { 74 return ( 75 // Setup the auth context and render our layout inside of it. 76 <Provider> 77 <Slot /> 78 </Provider> 79 ); 80} 81``` 82 83Now we can create our `(auth)` group which is unprotected, this screen can toggle the authentication using `signIn()`. 84 85```js app/(auth)/sign-in.js 86import { Text, View } from 'react-native'; 87import { useAuth } from '../../context/auth'; 88 89export default function SignIn() { 90 const { signIn } = useAuth(); 91 return ( 92 <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> 93 <Text onPress={() => signIn()}>Sign In</Text> 94 </View> 95 ); 96} 97``` 98 99And finally we'll implement an authenticated screen which can sign out. 100 101```js app/index.js 102import { Text, View } from 'react-native'; 103 104import { useAuth } from '../context/auth'; 105 106export default function Index() { 107 const { signOut } = useAuth(); 108 return ( 109 <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> 110 <Text onPress={() => signOut()}>Sign Out</Text> 111 </View> 112 ); 113} 114``` 115 116Now if the authentication state changes globally, the user will be redirected to the appropriate route. 117 118{/* TODO: Guide on using redirects and per-screen behavior */} 119