CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-navigation--native

React Native integration for React Navigation providing navigation containers, deep linking, and platform-specific navigation behaviors.

Pending
Overview
Eval results
Files

deep-linking.mddocs/

Deep Linking

Deep linking enables navigation to specific screens in your app using URLs. React Navigation provides comprehensive URL-based navigation with path matching, prefixes, and state synchronization.

Capabilities

Linking Options Configuration

Configure deep linking behavior through the NavigationContainer's linking prop.

interface LinkingOptions<ParamList extends {}> {
  /** Whether deep link handling should be enabled. Defaults to true when linking options are provided */
  enabled?: boolean;
  /** URL prefixes to match against. Stripped from URLs before parsing */
  prefixes: string[];
  /** Optional function to filter which URLs should be handled */
  filter?: (url: string) => boolean;
  /** Path configuration for mapping URLs to navigation state */
  config?: {
    /** Root path for the entire navigation tree */
    path?: string;
    /** Screen path configurations */
    screens: PathConfigMap<ParamList>;
    /** Name of the initial route for the root navigator */
    initialRouteName?: keyof ParamList;
  };
  /** Custom function to get the initial URL. Defaults to Linking.getInitialURL() */
  getInitialURL?: () => string | null | undefined | Promise<string | null | undefined>;
  /** Custom function to subscribe to URL updates */
  subscribe?: (listener: (url: string) => void) => undefined | void | (() => void);
  /** Custom function to parse URL to navigation state */
  getStateFromPath?: typeof getStateFromPath;
  /** Custom function to convert navigation state to URL */
  getPathFromState?: typeof getPathFromState;
  /** Custom function to convert navigation state to action */
  getActionFromState?: typeof getActionFromState;
}

type PathConfigMap<ParamList> = {
  [RouteName in keyof ParamList]: string | PathConfig<ParamList[RouteName]>;
};

interface PathConfig<ParamList> {
  path?: string;
  exact?: boolean;
  screens?: PathConfigMap<ParamList>;
  initialRouteName?: keyof ParamList;
  parse?: { [Param in keyof ParamList]?: (value: string) => ParamList[Param] };
  stringify?: { [Param in keyof ParamList]?: (value: ParamList[Param]) => string };
}

Usage Examples:

import { NavigationContainer } from '@react-navigation/native';

// Basic deep linking setup
const linking = {
  prefixes: ['myapp://'],
  config: {
    screens: {
      Home: 'home',
      Profile: 'profile/:id',
      Settings: 'settings',
    },
  },
};

function App() {
  return (
    <NavigationContainer linking={linking}>
      {/* Your navigators */}
    </NavigationContainer>
  );
}

// Advanced configuration with nested navigators
const advancedLinking = {
  prefixes: ['myapp://', 'https://myapp.com'],
  config: {
    screens: {
      Auth: {
        screens: {
          Login: 'login',
          Register: 'register',
        },
      },
      Main: {
        screens: {
          Home: 'home',
          Profile: {
            path: 'profile/:id',
            parse: {
              id: (id: string) => parseInt(id, 10),
            },
          },
          Settings: {
            path: 'settings',
            screens: {
              Account: 'account',
              Privacy: 'privacy',
            },
          },
        },
      },
    },
  },
};

// With URL filtering
const filteredLinking = {
  prefixes: ['myapp://'],
  filter: (url: string) => !url.includes('oauth-callback'),
  config: {
    screens: {
      Home: 'home',
      Profile: 'profile/:id',
    },
  },
};

URL Prefixes

Define which URL schemes and hosts your app should handle.

interface LinkingOptions<ParamList> {
  /** 
   * The prefixes are stripped from the URL before parsing them.
   * Usually they are the scheme + host (e.g. myapp://chat?user=jane)
   * This is not supported on Web.
   */
  prefixes: string[];
}

Usage Examples:

// App-specific scheme
const linking = {
  prefixes: ['myapp://'],
  // myapp://profile/123 -> profile/123
};

// Universal links
const universalLinking = {
  prefixes: ['https://example.com'],
  // https://example.com/profile/123 -> profile/123
};

// Multiple prefixes with wildcards
const multiPrefixLinking = {
  prefixes: [
    'myapp://',
    'https://example.com',
    'https://*.example.com', // Matches any subdomain
  ],
};

// Development and production
const environmentLinking = {
  prefixes: [
    'myapp://',
    __DEV__ 
      ? 'https://dev.example.com'
      : 'https://example.com',
  ],
};

Path Configuration

Map URL paths to navigation screens with parameter parsing.

interface PathConfig<ParamList> {
  /** Path pattern to match (e.g., 'profile/:id') */
  path?: string;
  /** Whether the path should match exactly */
  exact?: boolean;
  /** Nested screen configurations */
  screens?: PathConfigMap<ParamList>;
  /** Initial route name for nested navigators */
  initialRouteName?: keyof ParamList;
  /** Functions to parse URL parameters */
  parse?: { [Param in keyof ParamList]?: (value: string) => ParamList[Param] };
  /** Functions to stringify parameters for URL generation */
  stringify?: { [Param in keyof ParamList]?: (value: ParamList[Param]) => string };
}

Usage Examples:

// Simple path mapping
const config = {
  screens: {
    Home: 'home',
    About: 'about',
    Contact: 'contact',
  },
};

// Paths with parameters
const paramsConfig = {
  screens: {
    Profile: 'profile/:id',
    Article: 'article/:slug',
    Category: 'category/:name/page/:page',
  },
};

// Parameter parsing and validation
const parsedConfig = {
  screens: {
    Profile: {
      path: 'profile/:id',
      parse: {
        id: (id: string) => {
          const parsed = parseInt(id, 10);
          return isNaN(parsed) ? 0 : parsed;
        },
      },
    },
    Search: {
      path: 'search',
      parse: {
        q: (query: string) => decodeURIComponent(query),
        page: (page: string) => Math.max(1, parseInt(page, 10)),
      },
    },
  },
};

// Nested navigator configuration
const nestedConfig = {
  screens: {
    Home: 'home',
    Shop: {
      path: 'shop',
      screens: {
        ProductList: 'products',
        ProductDetail: 'product/:id',
        Cart: 'cart',
        Checkout: {
          path: 'checkout',
          screens: {
            Shipping: 'shipping',
            Payment: 'payment',
            Confirmation: 'confirmation',
          },
        },
      },
    },
  },
};

URL Filtering

Control which URLs should be handled by your navigation system.

interface LinkingOptions<ParamList> {
  /**
   * Optional function which takes an incoming URL and returns a boolean
   * indicating whether React Navigation should handle it.
   * This can be used to disable deep linking for specific URLs.
   */
  filter?: (url: string) => boolean;
}

Usage Examples:

// Filter out authentication callbacks
const authFilterLinking = {
  prefixes: ['myapp://'],
  filter: (url: string) => !url.includes('oauth-callback'),
  config: {
    screens: {
      Home: 'home',
      Profile: 'profile/:id',
    },
  },
};

// Filter based on URL patterns
const patternFilterLinking = {
  prefixes: ['myapp://'],
  filter: (url: string) => {
    // Don't handle admin URLs
    if (url.includes('/admin/')) return false;
    // Don't handle external redirects
    if (url.includes('redirect=')) return false;
    // Handle everything else
    return true;
  },
};

Custom URL Handling

Implement custom logic for URL processing and state management.

interface LinkingOptions<ParamList> {
  /** Custom function to get the initial URL used for linking */
  getInitialURL?: () => string | null | undefined | Promise<string | null | undefined>;
  /** Custom function to subscribe to URL updates */
  subscribe?: (listener: (url: string) => void) => undefined | void | (() => void);
  /** Custom function to parse URL to navigation state (advanced) */
  getStateFromPath?: typeof getStateFromPath;
  /** Custom function to convert state to URL (advanced) */
  getPathFromState?: typeof getPathFromState;
  /** Custom function to convert state to action (advanced) */
  getActionFromState?: typeof getActionFromState;
}

Usage Examples:

import { Linking } from 'react-native';

// Custom initial URL handling
const customInitialURL = {
  prefixes: ['myapp://'],
  getInitialURL: async () => {
    // Check if app was opened from a deep link
    const url = await Linking.getInitialURL();
    
    // Custom logic for handling the initial URL
    if (url?.includes('special-link')) {
      // Transform or validate the URL
      return url.replace('special-link', 'normal-link');
    }
    
    return url;
  },
};

// Custom URL subscription
const customSubscription = {
  prefixes: ['myapp://'],
  subscribe: (listener: (url: string) => void) => {
    // Custom URL change handling
    const onReceiveURL = ({ url }: { url: string }) => {
      // Apply custom transformations or filtering
      if (url.includes('valid-prefix')) {
        listener(url);
      }
    };

    const subscription = Linking.addEventListener('url', onReceiveURL);
    
    return () => subscription?.remove();
  },
};

// Custom state parsing
const customStateParsing = {
  prefixes: ['myapp://'],
  getStateFromPath: (path: string, config: any) => {
    // Custom logic to convert path to navigation state
    if (path.startsWith('/legacy/')) {
      // Handle legacy URL format
      const newPath = path.replace('/legacy/', '/');
      return getStateFromPath(newPath, config);
    }
    
    // Use default parsing for other paths
    return getStateFromPath(path, config);
  },
};

Error Handling

Handle cases where deep links cannot be processed or lead to invalid states.

// Invalid URLs that don't match any configured path will be ignored
// Use NavigationContainer's onUnhandledAction prop to handle edge cases

function App() {
  const handleUnhandledAction = (action: NavigationAction) => {
    console.warn('Unhandled navigation action:', action);
    // Custom error handling or fallback navigation
  };

  return (
    <NavigationContainer 
      linking={linking}
      onUnhandledAction={handleUnhandledAction}
    >
      {/* Your navigators */}
    </NavigationContainer>
  );
}

Install with Tessl CLI

npx tessl i tessl/npm-react-navigation--native

docs

deep-linking.md

index.md

link-components.md

navigation-container.md

navigation-hooks.md

server-side-rendering.md

static-navigation.md

theming.md

tile.json