Type-Safe Compose Navigation 🧭🚀
A strict guideline prohibiting legacy string-based navigation in Jetpack Compose, enforcing the modern Kotlinx Serialization approach for robust, crash-free routing.
⚡ When to Use
- Creating a NavHost: Scaffolding the screen routing for a new app.
- Passing Arguments: Sending IDs, details, or objects between screens.
- Refactoring Navigation: Upgrading a codebase from string-based routes to Type-Safe routes.
🚫 The Anti-Pattern (String Routes)
NEVER DO THIS. AI Agents trained on older data routinely hallucinate this pattern. It is fragile, cannot pass complex objects easily, and crashes frequently if strings are mismatched:
// BAD - DO NOT USE
navController.navigate("profile/${user.id}")
✅ The Standard (Type-Safe Navigation)
ALWAYS DO THIS. Use Compose Navigation 2.8.0+ and kotlinx.serialization.
1. Define Routes as Data Objects/Classes
In your presentation layer, define the screens using @Serializable.
import kotlinx.serialization.Serializable
@Serializable
object HomeRoute
@Serializable
data class ProfileRoute(val userId: String, val isLoggedIn: Boolean)
2. Scaffold the NavHost
Use the objects/classes directly in the NavHost builder.
NavHost(navController = navController, startDestination = HomeRoute) {
composable<HomeRoute> {
HomeScreen(
id ->
navController.navigate(ProfileRoute(userId = id, isLoggedIn = true))
}
)
}
composable<ProfileRoute> { backStackEntry ->
// Extract arguments safely!
val profile: ProfileRoute = backStackEntry.toRoute()
ProfileScreen(userId = profile.userId)
}
}
3. Agent Guardrails for Navigation
- Dependencies: Ensure
androidx.navigation:navigation-compose:2.8.+andorg.jetbrains.kotlinx:kotlinx-serialization-jsonare in thebuild.gradle.kts. - Plugins: Ensure
alias(libs.plugins.kotlin.serialization)is applied in the module-levelbuild.gradle.kts. - No Strings Attached: If you type
"/"or"?"inside anavigate()call, you are breaking the rules of this workspace. Use@Serializabledata classes.