Auth Flow

Basics

Protected screens allow you to prevent users from accessing certain routes using client-side navigation.

If a user tries to navigate to a protected screen, or if a screen becomes protected while it is active, they will be redirected to the anchor route (usually the index screen) or the first available screen in the stack.

Client side protection is more for user experience than security.

You cannot entirely rely on client side protection for security.

  • You need to implement the security logic on the server side to accept/reject requests.
  • Assuming every client request is stateless and can be malicious.

How to render based on auth

You would typically have a redirect rule based on auth status:

import { Redirect, Tabs } from 'expo-router'; if (!isLoggedIn) { return <Redirect href="/login" />; }

_layout.tsx is above all other screens in same directory.

However, the root layout does not support redirect to itself (since /login is placed in root _layout.tsx). Instead, we need to wrap all protected routes in /(protected):

/app /(protected) /(tabs) modals.tsx _layout.tsx # <Redirect /> login.tsx # plainly accessible without authentication _layout.tsx # <Redirect /> _layout.tsx # # holds redirects

You have to place redirect rule in every level of _layout.tsx that is protected.

Rendering order and project structure

Root _layout.tsx always gets rendered first.

  • then inner _layout.tsx gets rendered.

The rendering engine traverses inwards in each level of nested directories until it reaches an index.tsx that reflects a default / route.

This makes /(protected)/_layout.tsx the appropriate place for placing authenticated related code.

Because _layout.tsx is the first file to get rendered in same directory level, all protected route's visibility is determined by the rules defined in /(protected)/_layout.tsx.