> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mobile-starter.amisi.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Navigation

> Use typed routes, guards, transitions, and deep link helpers

# @amisi/navigation

`@amisi/navigation` provides router helpers, navigation guards, and deep linking utilities for Expo Router applications.

## Features

* **Deep link configuration** - Parse and build deep links with type safety
* **Navigation guards** - Protect routes based on auth, onboarding, subscription status
* **Transition presets** - Reusable stack navigation transitions
* **Typed routes** - Type-safe route helpers and navigation

## Deep Linking

### Create linking configuration

```ts theme={null}
import { createLinkingConfig } from '@amisi/navigation';

const linking = createLinkingConfig({
  scheme: 'myapp',
  prefixes: ['https://myapp.com', 'myapp://'],
});
```

### Parse deep links

```ts theme={null}
import { parseDeepLink } from '@amisi/navigation';

const parsed = parseDeepLink('myapp://profile/123');
// { screen: 'Profile', params: { id: '123' } }
```

### Build deep links

```ts theme={null}
import { buildDeepLink } from '@amisi/navigation';

const url = buildDeepLink('myapp', 'Profile', { userId: '123' });
// 'myapp://profile?userId=123'
```

### Check route types

```ts theme={null}
import { isAuthenticatedRoute, isOnboardingRoute } from '@amisi/navigation';

if (isAuthenticatedRoute('Profile')) {
  // Redirect to sign in if not authenticated
}

if (isOnboardingRoute('Welcome')) {
  // Show onboarding flow
}
```

## Navigation Guards

Guards prevent screen flashing and protect routes based on app state.

### AuthGate

Protect authenticated routes and redirect unauthenticated users:

```tsx theme={null}
import { AuthGate } from '@amisi/navigation';
import { useAuthContext } from '@amisi/auth';

export default function RootLayout() {
  const { session, loading } = useAuthContext();

  return (
    <AuthGate
      isAuthenticated={!!session}
      isLoading={loading}
      fallback={<LoadingScreen />}
      redirectTo="/sign-in"
    >
      <Stack />
    </AuthGate>
  );
}
```

### OnboardingGate

Ensure users complete onboarding before accessing the app:

```tsx theme={null}
import { OnboardingGate } from '@amisi/navigation';

<OnboardingGate
  hasCompletedOnboarding={user?.onboardingComplete}
  isLoading={loading}
  redirectTo="/onboarding"
>
  <MainApp />
</OnboardingGate>;
```

### SubscriptionGate

Require active subscription for premium features:

```tsx theme={null}
import { SubscriptionGate } from '@amisi/navigation';
import { useSubscriptions } from '@amisi/subscriptions';

export function PremiumFeature() {
  const { status, loading } = useSubscriptions();

  return (
    <SubscriptionGate
      hasActiveSubscription={status?.isActive ?? false}
      isLoading={loading}
      redirectTo="/subscription"
    >
      <PremiumContent />
    </SubscriptionGate>
  );
}
```

### AppLockGate

Handle app lock/unlock state:

```tsx theme={null}
import { AppLockGate } from '@amisi/navigation';
import { useAppLock } from '@amisi/app-lock';

export function App() {
  const { isLocked, loading, unlock } = useAppLock();

  return (
    <AppLockGate
      isLocked={isLocked}
      isLoading={loading}
      onUnlock={unlock}
      fallback={<SplashScreen />}
    >
      <MainApp />
    </AppLockGate>
  );
}
```

### ComposedGate

Combine multiple guards:

```tsx theme={null}
import { ComposedGate } from '@amisi/navigation';

<ComposedGate
  guards={[
    { condition: isAuthenticated, redirectTo: '/sign-in' },
    { condition: hasCompletedOnboarding, redirectTo: '/onboarding' },
    { condition: !isLocked, redirectTo: '/lock' },
  ]}
  fallback={<LoadingScreen />}
>
  <MainApp />
</ComposedGate>;
```

## Transition Presets

Reusable navigation transitions for consistent animations.

### Using presets

```tsx theme={null}
import { transitionPresets } from '@amisi/navigation';

<Stack.Screen
  name="modal"
  options={transitionPresets.modal}
/>

<Stack.Screen
  name="auth"
  options={transitionPresets.fade}
/>
```

### Available presets

* **modal** - Standard modal presentation
* **transparentModal** - Modal with transparent background
* **slideFromRight** - Horizontal slide (default stack)
* **slideFromBottom** - Vertical slide
* **fade** - Fade in/out
* **noAnimation** - No animation
* **auth** - Fade transition for auth screens
* **onboarding** - Horizontal slide for onboarding
* **tabBar** - Fade for tab navigation
* **platformModal** - Platform-specific modal (iOS modal, Android slide)
* **platformAuth** - Platform-specific auth (iOS fade, Android slide)

### Platform-specific transitions

```tsx theme={null}
import {
  getTransitionForPlatform,
  fadeTransition,
  slideFromRightTransition,
} from '@amisi/navigation';

const customTransition = getTransitionForPlatform(
  fadeTransition,
  slideFromRightTransition,
);
```

### Custom transitions

```tsx theme={null}
import { createCustomTransition } from '@amisi/navigation';

const myTransition = createCustomTransition({
  gestureEnabled: true,
  gestureDirection: 'horizontal',
  animationEnabled: true,
});
```

## Typed Routes

Type-safe route helpers and navigation.

### Route constants

```ts theme={null}
import { routes } from '@amisi/navigation';

// Navigate to routes
router.push(routes.home());
// '/'

router.push(routes.profile('user123'));
// '/profile/user123'

router.push(routes.details('item456'));
// '/details/item456'
```

### Build routes with params

```ts theme={null}
import { buildRoute } from '@amisi/navigation';

const path = buildRoute('/profile', { tab: 'settings', edit: true });
// '/profile?tab=settings&edit=true'
```

### Parse routes

```ts theme={null}
import { parseRoute } from '@amisi/navigation';

const { pathname, params } = parseRoute('/profile?tab=settings');
// { pathname: '/profile', params: { tab: 'settings' } }
```

### Match routes with patterns

```ts theme={null}
import { matchRoute } from '@amisi/navigation';

const { match, params } = matchRoute('/details/123', '/details/:id');
// { match: true, params: { id: '123' } }
```

### Route type checking

```ts theme={null}
import { isModalRoute, isAuthRoute, isProtectedRoute } from '@amisi/navigation';

if (isModalRoute('details')) {
  // Use modal transition
}

if (isAuthRoute('signIn')) {
  // Don't require authentication
}

if (isProtectedRoute('home')) {
  // Require authentication
}
```

### Get initial route

```ts theme={null}
import { getInitialRoute } from '@amisi/navigation';

const initialRoute = getInitialRoute(isAuthenticated, hasCompletedOnboarding);
// Returns: 'SignIn' | 'Welcome' | 'Home'
```

## Navigation State Helpers

```ts theme={null}
import {
  getActiveRouteName,
  getPreviousRouteName,
  canGoBack,
} from '@amisi/navigation';

const currentRoute = getActiveRouteName(navigationState);
const previousRoute = getPreviousRouteName(navigationState);
const canNavigateBack = canGoBack(navigationState);
```

## Architecture Benefits

This package solves common navigation pain points:

1. **Deep link → correct stack** - Parse and route deep links to the right screen
2. **Modal routes** - Consistent modal presentation across platforms
3. **No screen flashing** - Guards prevent showing wrong screens during state changes
4. **Type safety** - Typed route helpers prevent navigation errors
5. **Reusable transitions** - Consistent animations across the app
6. **Composable guards** - Combine multiple protection layers easily

## Example: Complete Setup

```tsx theme={null}
import { Stack } from 'expo-router';
import { AuthGate, OnboardingGate, transitionPresets } from '@amisi/navigation';
import { useAuthContext } from '@amisi/auth';

export default function RootLayout() {
  const { session, loading } = useAuthContext();

  return (
    <AuthGate
      isAuthenticated={!!session}
      isLoading={loading}
      fallback={<LoadingScreen />}
    >
      <OnboardingGate
        hasCompletedOnboarding={session?.user?.onboardingComplete}
        isLoading={loading}
      >
        <Stack>
          <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
          <Stack.Screen name="modal" options={transitionPresets.modal} />
          <Stack.Screen
            name="details/[id]"
            options={transitionPresets.slideFromRight}
          />
        </Stack>
      </OnboardingGate>
    </AuthGate>
  );
}
```
