Skip to main content
โšก Calmops

Expo Router Deep Dive: File-Based Navigation for React Native 2026

Introduction

Expo Router brings file-based routing to React Native, similar to Next.js. Create routes by adding files to your app directory. This guide covers everything you need.


How It Works

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                 Expo Router Concept                            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                             โ”‚
โ”‚  File System = Routes                                       โ”‚
โ”‚                                                             โ”‚
โ”‚  app/                          Screen                       โ”‚
โ”‚  โ”œโ”€โ”€ _layout.tsx              โ†’ Root layout                  โ”‚
โ”‚  โ”œโ”€โ”€ index.tsx                โ†’ / (Home)                    โ”‚
โ”‚  โ”œโ”€โ”€ about.tsx                โ†’ /about                      โ”‚
โ”‚  โ”œโ”€โ”€ users/                   โ†’ /users                     โ”‚
โ”‚  โ”‚   โ”œโ”€โ”€ _layout.tsx          โ†’ Users layout               โ”‚
โ”‚  โ”‚   โ”œโ”€โ”€ index.tsx            โ†’ /users                     โ”‚
โ”‚  โ”‚   โ””โ”€โ”€ [id].tsx            โ†’ /users/:id                 โ”‚
โ”‚  โ””โ”€โ”€ (stack).tsx             โ†’ Optional segment            โ”‚
โ”‚                                                             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Basic Setup

Installation

npx create-expo-app@latest my-app
cd my-app
npx expo-router start

Configuration

// app.json
{
  "expo": {
    "scheme": "myapp",
    "web": {
      "bundler": "metro"
    }
  }
}

Creating Routes

Simple Routes

// app/index.tsx - Home screen
import { View, Text } from 'react-native';
import { Link } from 'expo-router';

export default function Home() {
  return (
    <View>
      <Text>Welcome!</Text>
      <Link href="/about">Go to About</Link>
    </View>
  );
}

// app/about.tsx - About screen
import { View, Text } from 'react-native';
import { Stack } from 'expo-router';

export default function About() {
  return (
    <View>
      <Stack.Screen options={{ title: 'About Us' }} />
      <Text>About page content</Text>
    </View>
  );
}

Layouts

// app/_layout.tsx - Root layout
import { Stack } from 'expo-router';

export default function RootLayout() {
  return (
    <Stack>
      <Stack.Screen name="index" options={{ title: 'Home' }} />
      <Stack.Screen name="about" options={{ title: 'About' }} />
    </Stack>
  );
}

// app/tabs/_layout.tsx - Tab layout
import { Tabs } from 'expo-router';

export default function TabLayout() {
  return (
    <Tabs>
      <Tabs.Screen name="index" options={{ title: 'Home' }} />
      <Tabs.Screen name="profile" options={{ title: 'Profile' }} />
    </Tabs>
  );
}

Dynamic Routes

Parameters

// app/users/[id].tsx - Dynamic route
import { useLocalSearchParams } from 'expo-router';

export default function UserProfile() {
  const { id } = useLocalSearchParams();
  
  return (
    <View>
      <Text>User ID: {id}</Text>
    </View>
  );
}

// app/posts/[...slug].tsx - Catch-all route
import { useLocalSearchParams } from 'expo-router';

export default function Post() {
  const { slug } = useLocalSearchParams();
  const slugArray = Array.isArray(slug) ? slug : [slug];
  
  return (
    <Text>Post: {slugArray.join('/')}</Text>
  );
}

Multiple Parameters

// app/users/[id]/posts/[postId].tsx
import { useLocalSearchParams } from 'expo-router';

export default function UserPost() {
  const { id, postId } = useLocalSearchParams();
  
  return (
    <Text>
      User {id}'s post: {postId}
    </Text>
  );
}

Programmatic Navigation

import { useRouter } from 'expo-router';

export function LoginButton() {
  const router = useRouter();
  
  return (
    <Button onPress={() => router.push('/dashboard')}>
      Login
    </Button>
  );
}

// Navigate with params
router.push({
  pathname: '/users/[id]',
  params: { id: '123' }
});

// Go back
router.back();

// Replace (no back navigation)
router.replace('/home');

Deep Linking

// app.json
{
  "expo": {
    "scheme": "myapp",
    "extra": {
      "eas": {
        "projectId": "..."
      }
    }
  }
}

// Deep link to screen
// myapp://users/123

API Reference

# Available hooks
hooks:
  - "useRouter" - Navigate programmatically
  - "useLocalSearchParams" - Get route params
  - "useGlobalSearchParams" - Global URL params
  - "useNavigation" - React Navigation API
  - "useSegments" - Current route segments

Key Takeaways

  • File-based routing - Routes from file structure
  • Layouts - Shared UI for groups
  • Dynamic routes - Parameters in URLs
  • Deep linking - Built-in support

External Resources

Comments