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