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

static-navigation.mddocs/

Static Navigation

Static navigation enables type-safe navigation configuration by generating navigation components from static definitions. This approach provides compile-time type checking and automatic deep linking path generation.

Capabilities

createStaticNavigation Function

Creates a navigation component from a static navigation configuration tree.

/**
 * Create a navigation component from a static navigation config.
 * The returned component is a wrapper around NavigationContainer.
 */
function createStaticNavigation(
  tree: StaticNavigation<any, any, any>
): React.ForwardRefExoticComponent<
  StaticNavigationProps & React.RefAttributes<NavigationContainerRef<ParamListBase>>
>;

type StaticNavigationProps = Omit<
  React.ComponentProps<typeof NavigationContainer>,
  'linking' | 'children'
> & {
  /** Options for deep linking */
  linking?: Omit<LinkingOptions<ParamListBase>, 'config' | 'enabled'> & {
    /** Whether deep link handling should be enabled. 'auto' generates paths automatically */
    enabled?: 'auto' | true | false;
    /** Additional configuration excluding screens (auto-generated from tree) */
    config?: Omit<NonNullable<LinkingOptions<ParamListBase>['config']>, 'screens'>;
  };
};

Usage Examples:

import { createStaticNavigation } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

// Define screen components
function HomeScreen() {
  return <Text>Home Screen</Text>;
}

function ProfileScreen() {
  return <Text>Profile Screen</Text>;
}

function SettingsScreen() {
  return <Text>Settings Screen</Text>;
}

// Create static navigator configurations
const HomeStack = createStackNavigator({
  screens: {
    Home: HomeScreen,
    Profile: ProfileScreen,
  },
});

const SettingsStack = createStackNavigator({
  screens: {
    Settings: SettingsScreen,
  },
});

// Create root tab navigator
const RootTabs = createBottomTabNavigator({
  screens: {
    HomeTab: HomeStack,
    SettingsTab: SettingsStack,
  },
});

// Generate the navigation component
const Navigation = createStaticNavigation(RootTabs);

// Use in your app
function App() {
  return <Navigation />;
}

Static Navigation Configuration

Define navigation structure using static configuration objects with full type safety.

// StaticNavigation types are provided by individual navigator packages
interface StaticNavigation<
  ScreenOptions,
  NavigatorOptions,
  EventMap
> {
  screens: Record<string, StaticNavigation<any, any, any> | React.ComponentType>;
  navigatorOptions?: NavigatorOptions;
  screenOptions?: ScreenOptions | ((props: any) => ScreenOptions);
}

Configuration Examples:

// Simple stack configuration
const SimpleStack = createStackNavigator({
  screens: {
    Home: HomeScreen,
    Details: DetailsScreen,
  },
});

// Stack with screen options
const StyledStack = createStackNavigator({
  screens: {
    Home: {
      screen: HomeScreen,
      options: {
        title: 'Welcome',
        headerStyle: { backgroundColor: '#007AFF' },
      },
    },
    Profile: {
      screen: ProfileScreen,
      options: ({ route }) => ({
        title: route.params?.name || 'Profile',
      }),
    },
  },
  screenOptions: {
    headerTintColor: '#fff',
  },
});

// Nested navigator configuration
const RootNavigator = createStackNavigator({
  screens: {
    Auth: createStackNavigator({
      screens: {
        Login: LoginScreen,
        Register: RegisterScreen,
      },
      screenOptions: {
        headerShown: false,
      },
    }),
    Main: createBottomTabNavigator({
      screens: {
        Home: HomeStack,
        Profile: ProfileStack,
        Settings: SettingsScreen,
      },
    }),
  },
});

// Complex nested structure
const AppNavigator = createStackNavigator({
  screens: {
    Onboarding: OnboardingScreen,
    Main: createBottomTabNavigator({
      screens: {
        Feed: createStackNavigator({
          screens: {
            FeedList: FeedListScreen,
            Post: PostScreen,
            Comments: CommentsScreen,
          },
        }),
        Search: createStackNavigator({
          screens: {
            SearchHome: SearchHomeScreen,
            SearchResults: SearchResultsScreen,
            SearchFilters: SearchFiltersScreen,
          },
        }),
        Profile: createStackNavigator({
          screens: {
            ProfileHome: ProfileHomeScreen,
            ProfileEdit: ProfileEditScreen,
            ProfileSettings: ProfileSettingsScreen,
          },
        }),
      },
    }),
  },
});

Automatic Deep Linking

Static navigation can automatically generate deep linking paths based on the navigation structure.

// Linking configuration for static navigation
interface StaticLinkingConfig {
  /** Whether to enable automatic path generation */
  enabled?: 'auto' | true | false;
  /** URL prefixes to handle */
  prefixes?: string[];
  /** Additional configuration excluding auto-generated screens */
  config?: {
    path?: string;
    initialRouteName?: string;
  };
}

Deep Linking Examples:

// Automatic path generation
const Navigation = createStaticNavigation(RootNavigator);

function App() {
  return (
    <Navigation
      linking={{
        enabled: 'auto', // Generates paths automatically
        prefixes: ['myapp://'],
      }}
    />
  );
}

// Generated paths would be:
// myapp://onboarding -> Onboarding screen
// myapp://main/feed/feed-list -> FeedList screen
// myapp://main/feed/post -> Post screen
// myapp://main/search/search-home -> SearchHome screen
// myapp://main/profile/profile-home -> ProfileHome screen

// Manual path configuration
function AppWithCustomPaths() {
  return (
    <Navigation
      linking={{
        enabled: true,
        prefixes: ['myapp://'],
        config: {
          initialRouteName: 'Main',
        },
        // Custom path mappings override auto-generated ones
        screens: {
          Main: {
            screens: {
              Feed: {
                screens: {
                  FeedList: 'home',
                  Post: 'post/:id',
                },
              },
              Profile: {
                screens: {
                  ProfileHome: 'profile',
                  ProfileEdit: 'profile/edit',
                },
              },
            },
          },
        },
      }}
    />
  );
}

// Disable linking entirely
function AppWithoutLinking() {
  return (
    <Navigation
      linking={{
        enabled: false,
      }}
    />
  );
}

Type Safety

Static navigation provides compile-time type checking for navigation operations.

// Type-safe navigation with static configuration
declare global {
  namespace ReactNavigation {
    interface RootParamList {
      Home: undefined;
      Profile: { userId: string };
      Settings: undefined;
      Post: { id: number; slug?: string };
    }
  }
}

Type Safety Examples:

// Navigation component with full type safety
const TypedNavigation = createStaticNavigation(
  createStackNavigator({
    screens: {
      Home: HomeScreen,
      Profile: ProfileScreen, // Expects { userId: string }
      Post: PostScreen,       // Expects { id: number; slug?: string }
    },
  })
);

// Type-safe navigation in components
function HomeScreen() {
  const navigation = useNavigation();

  const goToProfile = () => {
    // ✅ TypeScript ensures correct params
    navigation.navigate('Profile', { userId: '123' });
  };

  const goToPost = () => {
    // ✅ Optional params work correctly
    navigation.navigate('Post', { id: 1, slug: 'my-post' });
  };

  const invalidNavigation = () => {
    // ❌ TypeScript error - missing required userId
    navigation.navigate('Profile');
    
    // ❌ TypeScript error - wrong param type
    navigation.navigate('Post', { id: '123' });
  };

  return (
    <View>
      <Button title="Go to Profile" onPress={goToProfile} />
      <Button title="Go to Post" onPress={goToPost} />
    </View>
  );
}

// Type-safe links
function TypedLinks() {
  return (
    <View>
      {/* ✅ Correct typing */}
      <Link screen="Profile" params={{ userId: '123' }}>
        Profile
      </Link>
      
      {/* ❌ TypeScript error - missing required param */}
      <Link screen="Profile">
        Profile
      </Link>
    </View>
  );
}

Navigation Ref Integration

Static navigation components support ref forwarding for programmatic navigation.

// Ref type for static navigation
type StaticNavigationRef = NavigationContainerRef<ParamListBase>;

Ref Usage Examples:

import { useRef } from 'react';
import type { NavigationContainerRef } from '@react-navigation/native';

function App() {
  const navigationRef = useRef<NavigationContainerRef<RootParamList>>(null);

  const handleDeepLink = (url: string) => {
    // Parse URL and navigate programmatically
    if (url.includes('/profile/')) {
      const userId = extractUserId(url);
      navigationRef.current?.navigate('Profile', { userId });
    }
  };

  return (
    <Navigation
      ref={navigationRef}
      onReady={() => {
        console.log('Navigation ready');
        // Can safely use navigationRef.current here
      }}
      onStateChange={(state) => {
        console.log('Navigation state changed:', state);
      }}
    />
  );
}

// Using navigation ref with external libraries
function AppWithAnalytics() {
  const navigationRef = useRef<NavigationContainerRef<RootParamList>>(null);

  return (
    <Navigation
      ref={navigationRef}
      onStateChange={(state) => {
        const currentRoute = navigationRef.current?.getCurrentRoute();
        if (currentRoute) {
          analytics.track('Screen View', {
            screen: currentRoute.name,
            params: currentRoute.params,
          });
        }
      }}
    />
  );
}

Integration with Navigator Libraries

Static navigation works with all React Navigation navigator libraries.

// Compatible navigator types
interface CompatibleNavigators {
  '@react-navigation/stack': typeof createStackNavigator;
  '@react-navigation/bottom-tabs': typeof createBottomTabNavigator;
  '@react-navigation/material-top-tabs': typeof createMaterialTopTabNavigator;
  '@react-navigation/drawer': typeof createDrawerNavigator;
  '@react-navigation/native-stack': typeof createNativeStackNavigator;
}

Multi-Navigator Examples:

import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createDrawerNavigator } from '@react-navigation/drawer';

// Complex navigation structure using multiple navigator types
const AppNavigator = createDrawerNavigator({
  screens: {
    Main: createBottomTabNavigator({
      screens: {
        Home: createStackNavigator({
          screens: {
            HomeList: HomeListScreen,
            HomeDetail: HomeDetailScreen,
          },
        }),
        Search: createStackNavigator({
          screens: {
            SearchHome: SearchHomeScreen,
            SearchResults: SearchResultsScreen,
          },
        }),
        Profile: ProfileScreen,
      },
    }),
    Settings: SettingsScreen,
    Help: HelpScreen,
  },
});

const Navigation = createStaticNavigation(AppNavigator);

function App() {
  return (
    <Navigation
      linking={{
        enabled: 'auto',
        prefixes: ['myapp://'],
      }}
    />
  );
}

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