Navigate to a destination

The Navigation component provides a simple way of navigating to a destination. This interface supports a range of contexts and UI frameworks. For example, you can use the Navigation component with Compose, Views, Fragments, Activities, and even custom UI frameworks.

The following guide describes how you can use the Navigation component to navigate to a destination in various contexts.

Role of the NavController

The NavController is the central navigation API. It tracks which destinations the user has visited, and its methods allow the user to move between destinations.

NavController provides a few different ways to navigate to a destination, which are described further in the following sections.

Create a NavController

To create a NavController when using Jetpack Compose, call rememberNavController(). See the Navigating with Compose guide for detailed information.

Retrieve a NavController using Views

If you are using the Views UI framework, you can retrieve your NavController using one of several methods, depending on the context. See the Get started guide for more information.

Regardless of which UI framework you use, there is a single function you can use to navigate to a destination: NavController.navigate().

There are many overloads available for navigate(). The overload you should choose corresponds to your exact context. For example, you should use one overload when navigating to a composable and another when navigating to a view.

The following sections outline some of the key navigate() overloads you can use.

Navigate to a composable

To navigate to a composable in the navigation graph, use NavController.navigate(route). With this overload, navigate() takes a single String argument. This is the route. It serves as the key to a destination.


To navigate using a route string, you first need to create your NavGraph such that each destination is associated with a route. For composables, you do so with the composable() function.

For more information, see the Create destinations guide.

When a composable function needs to navigate to a new screen, you shouldn't pass it a reference to the NavController so that it can call navigate() directly. According to Unidirectional Data Flow (UDF) principles, it should instead expose an event that the NavController handles.

More directly put, your composable should have a parameter of type () -> Unit. When you add destinations to your NavHost with the composable() function, pass your composable a call to NavController.navigate().

See the following subsection for a clear example of this.

As a demonstration of the preceding section, observe these points in the following snippet:

  1. The MyAppNavHost composable holds the NavController instance.
  2. Accordingly, calls to navigate() should occur there and not in a lower composable like ProfileScreen.
  3. ProfileScreen contains a button that navigates the user to FriendsList when clicked. However, it does not call navigate() itself.
  4. Instead, the button calls a function that is exposed as the parameter onNavigateToFriends.
  5. When MyAppNavHost adds ProfileScreen to the navigation graph, for onNavigateToFriends it passes a lambda that calls navigate().
  6. This ensures that when the user presses the button ProfileScreen, they navigate correctly to friendsList.
fun MyAppNavHost(
    modifier: Modifier = Modifier,
    navController: NavHostController = rememberNavController(),
    startDestination: String = "profile"
) {
        modifier = modifier,
        navController = navController,
        startDestination = startDestination
    ) {
        composable("profile") {
                onNavigateToFriends = { navController.navigate("friendsList") },
        composable("friendslist") { FriendsListScreen(/*...*/) }

fun ProfileScreen(
    onNavigateToFriends: () -> Unit,
) {
    Button(onClick = onNavigateToFriends) {
        Text(text = "See friends list")

Navigate using integer ID

To navigate to a destination using an integer ID, call the navigate(int) overload. It takes the resource ID of either an action or a destination. The following code snippet shows how you can use this overload to navigate to the ViewTransactionsFragment:


viewTransactionsButton.setOnClickListener { view ->


viewTransactionsButton.setOnClickListener(new View.OnClickListener() {
  public void onClick(View view) {

When navigating using IDs, you should use actions where possible. Actions provide additional information in your navigation graph, visually showing how your destinations connect to each other.

Navigate using DeepLinkRequest

To navigate to an implicit deep link destination, use the navigate(NavDeepLinkRequest) overload. The follow snippet provides an implementation of this method:


val request = NavDeepLinkRequest.Builder


NavDeepLinkRequest request = NavDeepLinkRequest.Builder

Unlike navigation using action or destination IDs, you can navigate to any deep link in your graph, regardless of whether the destination is visible. You can navigate to a destination on the current graph or a destination on a completely different graph.

Actions and MIME types

In addition to Uri, NavDeepLinkRequest also supports deep links with actions and MIME types. To add an action to the request, use fromAction() or setAction(). To add a MIME type to a request, use fromMimeType() or setMimeType().

For a NavDeepLinkRequest to properly match an implicit deep link destination, the URI, action, and MIME type must all match the NavDeepLink in the destination. URIs must match the pattern, the actions must be an exact match, and the MIME types must be related. For example, image/jpg matches with image/\*

Further contexts

This document covers how to use NavController.navigate() in the most common use cases. However, the function has a range of overloads that you can use in different contexts, and in tandem with any Ui framework. See the reference documentation for more detail on these overloads.

Further reading

For more information, see the following pages: