# Redirects for deprecated routes handled gracefully

- **Pattern:** `ab-001867` (`mobile-navigation-linking.navigation-ux.deprecated-route-redirects`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001867
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001867)

## Why it matters

Renamed or retired screens leave a long tail of deep links in the wild — old emails, shared URLs, indexed Google results, push-notification payloads from older app versions. Without aliases or a fallback handler, those links either crash the app or dump users on an unhandled route, breaking referral traffic and surfacing as negative store reviews. Reference-integrity on deep links is the mobile equivalent of HTTP 301 redirects on the web.

## Severity rationale

Low because most users use current links, but long-tail traffic and indexed URLs degrade silently without redirects.

## Remediation

Add deprecated-route aliases and a `fallback` handler to the linking config so old URLs resolve cleanly. In `src/navigation/linking.ts`:

```tsx
export const linking = {
  prefixes: ['myapp://', 'https://myapp.com'],
  config: {
    screens: {
      ProductDetail: 'product/:id',
      ProductView: 'product/:id', // deprecated alias
    },
  },
  getStateFromPath: (path, options) => {
    // fall through to Home if unresolved
    return getStateFromPath(path, options) ?? { routes: [{ name: 'Home' }] }
  },
}
```

## Detection

- **ID:** `deprecated-route-redirects`
- **Severity:** `low`
- **What to look for:** Check whether your app handles deprecated or changed route names. Look for fallback navigation logic in the deep link config. Examine whether old deep link URLs gracefully redirect to new screens rather than crashing or showing errors.
- **Pass criteria:** Count all deprecated or aliased route entries in the linking config. Deprecated route names are redirected to their new equivalents via aliases or a fallback handler. Old deep link URLs must be handled without crashing. At least 1 fallback or wildcard route must exist for unmatched paths.
- **Fail criteria:** Deep links to old/renamed screens crash the app or show error screens. No redirect logic for deprecated routes.
- **Skip (N/A) when:** The app has never renamed screens and has no backward compatibility needs for old deep links (first release).
- **Detail on fail:** `"Deep links to 'ProductView' (renamed to 'ProductDetail') cause app to crash"` or `"No fallback for deprecated route names"`
- **Remediation:** Add a fallback handler and route mapping to your linking config:

  ```tsx
  const linking = {
    prefixes: ['myapp://', 'https://myapp.com'],
    config: {
      screens: {
        Home: '',
        ProductDetail: 'product/:id',
        // Redirect old routes to new ones
        ProductView: 'product/:id', // deprecated alias
        Profile: 'profile/:userId',
        UserProfile: 'profile/:userId', // deprecated alias
      }
    },
    // Fallback handler for unmapped routes
    fallback: ({ path }) => {
      // Log or handle unmapped routes
      console.warn(`No route found for path: ${path}`)
      return ['Home']
    }
  }

  <NavigationContainer
    linking={linking}
    fallback={<LoadingScreen />} // Show while linking is being resolved
  >
    {/* navigators */}
  </NavigationContainer>
  ```

Taxons: reference-integrity, user-experience

HTML version: https://auditbuffet.com/patterns/ab-001867
