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