Chanzmao ʕ•ᴥ•ʔ Bear Blog

Navigation 3 Navigation Graph Patterns

Extension Functions, Sealed NavKeys, and Nested NavDisplay

Navigation 3 no longer uses nested navigation graphs like navigation() in the old Navigation Component.

Instead, you organize screens using one of these three patterns.

1. Group entries with extension functions

Split screen definitions by feature or module.

// AuthModule.kt
fun EntryProviderScope<NavKey>.authGraph() {
    entry<Login> { LoginScreen() }
    entry<SignUp> { SignUpScreen() }
}

// AppNavigation.kt
val entryProvider = entryProvider {
    authGraph()
    entry<Home> { HomeScreen() }
}

NavDisplay(
    backStack = backStack,
    entryProvider = entryProvider
)

This keeps navigation definitions modular while sharing a single NavBackStack.

2. Group NavKeys with sealed interfaces

Organize related destinations under the same namespace.

sealed interface AuthKey : NavKey {
    @Serializable
    data object Login : AuthKey

    @Serializable
    data object SignUp : AuthKey
}

sealed interface MainKey : NavKey {
    @Serializable
    data object Home : MainKey

    @Serializable
    data class Detail(val id: String) : MainKey
}

Usage is straightforward:

backStack.add(AuthKey.Login)
backStack.add(MainKey.Detail("123"))

This improves readability and keeps your navigation keys organized.

3. Nest NavDisplay for independent back stacks

If a flow needs its own navigation history—such as Bottom Navigation, tabs, or onboarding—create another NavDisplay.

entry<MainTabs> {
    MainTabsScreen()
}
@Composable
fun MainTabsScreen() {
    val tabBackStack = rememberNavBackStack(HomeTab)

    NavDisplay(
        backStack = tabBackStack,
        entryProvider = entryProvider {
            entry<HomeTab> { HomeScreen() }
            entry<SearchTab> { SearchScreen() }
            entry<ProfileTab> { ProfileScreen() }
        }
    )
}

Each NavDisplay manages its own NavBackStack, making navigation independent from its parent.

Choosing the right approach

Organize code?
    │
    ├── Yes
    │     ├── Extension functions
    │     └── Sealed NavKeys
    │
    └── Need an independent BackStack?
          └── Nest NavDisplay

These patterns can be combined, and each solves a different problem.

#Android #Jetpack Compose