Chapter 9 of 12 ~18 min read

Navigation & Deep Linking

Replacing single-page hash routing with Expo Router & React Navigation, native stack gestures.


1. Multi-Page Cordova vs Expo Router

In Cordova, navigation was either clumsy SPA hash swapping (#home, #details) or jarring full-page webview reloads (window.location.href = 'details.html').

Expo Router introduces file-based routing with real native view controllers:

File-Based Routing Structure (app/)
app/
├── _layout.tsx      # Root Stack Navigator & Theme Provider
├── index.tsx        # Home Screen ("/")
├── details.tsx      # Details Screen ("/details")
└── profile/
    ├── _layout.tsx  # Nested Stack/Tabs
    └── [id].tsx     # Dynamic route ("/profile/123")
Cordova Navigation
// Manual DOM swapping
function showPage(pageId) {
  document.querySelectorAll('.page').forEach(p => p.classList.remove('active'));
  document.getElementById(pageId).classList.add('active');
  window.history.pushState({}, '', '#' + pageId);
}
Expo Router Link
import { Link, useRouter } from 'expo-router';
import { View, Text, Pressable } from 'react-native';

export default function HomeScreen() {
  const router = useRouter();

  return (
    <View>
      {/* Declarative navigation */}
      <Link href="/details" asChild>
        <Pressable><Text>Go to Details</Text></Pressable>
      </Link>

      {/* Programmatic navigation */}
      <Pressable onPress={() => router.push('/profile/42')}>
        <Text>View Profile</Text>
      </Pressable>
    </View>
  );
}