Navigation¶
Starter Template uses navigation3 with Koin.
All navigation logic lives inside the features/navigation module.
1. Define Screens¶
Example:
| features/navigation/src/commonMain/.../screens/AuthScreens.kt | |
|---|---|
Rules
- Must be
@Serializable - Must extend
NavKey* Usesealed classper feature
2. Register Screens for Serialization¶
Add the screen to the back stack configuration:
| features/navigation/src/commonMain/.../StarterBackStack.kt | |
|---|---|
State Restoration
If a screen is not registered using subclass(...), state restoration will fail.
3. Define Navigation Routes (Koin)¶
| composeApp/src/commonMain/.../core/navigation/NavigationModule.kt | |
|---|---|
Custom Module
You can also create a custom module inside your feature di package,
don't forget to include it inside initKoin
4. Navigating Between Screens¶
Get navigator:
Available methods:
navigator.navigateTo(route)
navigator.popAndNavigate(route)
navigator.popAllAndNavigate(route)
navigator.navigateOrBringToTop(route)
navigator.navigateUp()
Example:
5. Changing Initial Screen¶
You can change the initial (starting) screen from App.kt.
By default, navigation starts from StarterScreens.Splash.
To change it, update the first parameter of StarterNavigation.
For example, to start directly from SignIn:
Keeping Splash → Onboarding → Your Screen Flow¶
If you want to keep the default flow:
You can control it inside the navigation module.
Nested Navigation¶
Starter Template provides utilities for creating nested navigation. This is very useful when you have a screen (like MainScreen) that has its own internal navigation, like Bottom Navigation.
Step 1: Define Your Nested Items¶
First, create a data class for your items and define the list of screens.
Defining Routes
We've already covered creating routes above. You should define your NestedScreens sealed class the same way.
Step 2: Register Nested Screens in Navigation Module¶
Now, tell Koin how to show these nested screens.
val navigationModule = module {
...
navigation<NestedScreens.Home> { route ->
HomeScreen()
}
navigation<NestedScreens.History> { route ->
HistoryScreen()
}
...
}
Optional: Custom Module
You can also create a custom navigation module inside your feature's di package. Don't forget to include it in initKoin. It's a good practice to name it like featureNameNestedNavModule.
Step 3: Initialize the Nested Backstack¶
In your parent screen (MainScreen), you need to manage the backstack for the nested navigation. We use the rememberNavBackStack utility from the feature_navigation module because it provides a much simpler syntax.
| MainScreen | |
|---|---|
Navigator is Optional
Creating a separate Navigator is usually optional for nested navigation. Since the parent screen (MainScreen) is usually only responsible for switching between these nested screens, you can just manipulate the backStack directly.
Step 4: Setup UI and NavDisplay¶
Finally, complete your UI using Scaffold and NavDisplay.
Navigation Flow
- Create screen (extend
NavKey) - Register in
StarterBackStack - Add route in
NavigationModuleor custom module - Use
StarterNavigatorto navigate - Change
inital screenif needed
Navigation is type-safe, serializable, and works across Compose Multiplatform.