A navigation graph can consist of any combination of the following:

- A singular destination, such as a`<fragment>`destination.
- A[nested graph](https://developer.android.com/guide/navigation/navigation-nested-graphs)that encapsulates a set of related destinations.
- An[`<include>`](https://developer.android.com/guide/navigation/navigation-nested-graphs#include)element, which allows you to embed another navigation graph file as though it was nested.

This flexibility allows you to combine smaller navigation graphs together to form your app's complete navigation graph, even if those smaller navigation graphs are provided by separate[modules](https://developer.android.com/topic/modularization).
| **Note:** This page assumes a basic familiarity with the[guide to Android app modularization](https://developer.android.com/topic/modularization). To learn how to provide type safety Navigation in a modularized project for the Kotlin DSL and Navigation Compose, check out the[Navigation type safety page](https://developer.android.com/guide/navigation/navigation-type-safety).
| **Key Term:** In the context of this guide a**feature module** is a module that encapsulates a distinct part of your application's functionality. However,**feature module** is a term that is also used in the[Play Feature Delivery](https://developer.android.com/guide/playcore/feature-delivery)describing a module that can be delivered conditionally or downloaded on-demand. Navigation supports[navigating with custom delivered feature modules](https://developer.android.com/guide/navigation/navigation-dynamic)and provides similar functionality for dynamic feature modules through[`<include-dynamic>`](https://developer.android.com/guide/navigation/navigation-dynamic#included).

For the examples in this topic, each[feature module](https://developer.android.com/topic/modularization/patterns#feature-modules)is focused around one[feature](https://developer.android.com/topic/modularization/patterns#feature-modules)and provides a single navigation graph that encapsulates all of the destinations needed to implement that feature. In a production app, you might have many submodules at a lower level that are implementation details of this higher-level feature module. Each of these feature modules are included, either directly or indirectly, into your[`app`module](https://developer.android.com/topic/modularization/patterns#app-modules). The example[multi-module application](https://developer.android.com/topic/modularization)used in this doc has the following structure:
![dependency graph for a sample multi-module application](https://developer.android.com/static/images/guide/navigation/multimodule-structure.png)  
![the start destination of the example app](https://developer.android.com/static/images/guide/navigation/multimodule-screen.png)**Figure 1.**App architecture and start destination for the example app.

Each feature module is a self-contained unit with its own navigation graph and destinations. The`app`module depends on each, adding them as implementation details in its`build.gradle`file, as shown:  

### Groovy

```groovy
dependencies {
    ...
    implementation project(":feature:home")
    implementation project(":feature:favorites")
    implementation project(":feature:settings")
```

### Kotlin

```kotlin
dependencies {
    ...
    implementation(project(":feature:home"))
    implementation(project(":feature:favorites"))
    implementation(project(":feature:settings"))
```

## The role of the`app`module

The[`app`](https://developer.android.com/topic/modularization/patterns#app-modules)module is responsible for providing the complete graph for your app and adding the`NavHost`to your UI. Within the`app`module's navigation graph, you can reference the library graphs by using[`<include>`](https://developer.android.com/guide/navigation/navigation-nested-graphs#include). While using`<include>`is functionally the same as using a nested graph,`<include>`supports graphs from other project modules or from library projects, as shown in the following example:  

    <?xml version="1.0" encoding="utf-8"?>
    <navigation xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/nav_graph"
        app:startDestination="@id/home_nav_graph">

        <include app:graph="@navigation/home_navigation" />
        <include app:graph="@navigation/favorites_navigation" />
        <include app:graph="@navigation/settings_navigation" />
    </navigation>

| **Note:** The graph attribute in the`<include>`tag references the name of the library's graph file (`home_navigation.xml`, for example). The`startDestination`references the ID of the`<navigation>`element within that file and specifically does not use`@+id`, instead using`@id/`to use the ID that is already declared in the feature module.

Once a library is included in the top-level navigation graph, you can[navigate](https://developer.android.com/guide/navigation/navigation-design-graph#navigation_across_library_modules)to the library graphs as needed. For example, you could create an action to navigate to the settings graph from a fragment in your navigation graph, as shown:  

    <?xml version="1.0" encoding="utf-8"?>
    <navigation xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/nav_graph"
        app:startDestination="@id/home_nav_graph">

        <include app:graph="@navigation/home_navigation" />
        <include app:graph="@navigation/favorites_navigation" />
        <include app:graph="@navigation/settings_navigation" />

        <fragment
            android:id="@+id/random_fragment"
            android:name="com.example.android.RandomFragment"
            android:label="@string/fragment_random" >
            <!-- Launch into Settings Navigation Graph -->
            <action
                android:id="@+id/action_random_fragment_to_settings_nav_graph"
                app:destination="@id/settings_nav_graph" />
        </fragment>
    </navigation>

When multiple feature modules need to reference a common set of destinations, such as a login graph, you**should not** include those common destinations into each feature module's navigation graph. Instead, add those common destinations to your`app`module's navigation graph. Each feature module can then[navigate across feature modules](https://developer.android.com/guide/navigation/integrations/multi-module#across)to navigate to those common destinations.

In the previous example, the action specifies a navigation destination of`@id/settings_nav_graph`. This ID refers to a destination that is defined within the included graph`@navigation/settings_navigation.`

## Top-level navigation in app module

The Navigation component includes a[`NavigationUI`](https://developer.android.com/reference/androidx/navigation/ui/NavigationUI)class. This class contains static methods that manage navigation with the top app bar, the navigation drawer, and bottom navigation. If your app's top-level destinations are composed of UI elements provided by feature modules, the`app`module is a natural place to put the top-level navigation and UI elements. Since the app module depends on the collaborating feature modules, all of their destinations are accessible from code defined within your app module. This means that you can use`NavigationUI`to[tie destinations to menu items](https://developer.android.com/guide/navigation/navigation-ui#Tie-navdrawer)if the ID of the item matches the ID of a destination.

In figure 2, the example`app`module defines a[`BottomNavigationView`](https://developer.android.com/reference/com/google/android/material/bottomnavigation/BottomNavigationView)in its main activity. The menu item IDs in the menu match the navigation graph IDs of the library graphs:  

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">

        <item
            android:id="@id/home_nav_graph"
            android:icon="@drawable/ic_home"
            android:title="Home"
            app:showAsAction="ifRoom"/>

        <item
            android:id="@id/favorites_nav_graph"
            android:icon="@drawable/ic_favorite"
            android:title="Favorites"
            app:showAsAction="ifRoom"/>

        <item
            android:id="@id/settings_nav_graph"
            android:icon="@drawable/ic_settings"
            android:title="Settings"
            app:showAsAction="ifRoom" />
    </menu>

To let`NavigationUI`handle the[bottom navigation](https://developer.android.com/guide/navigation/navigation-ui#bottom_navigation), call[`setupWithNavController()`](https://developer.android.com/reference/androidx/navigation/ui/NavigationUI#setupWithNavController(com.google.android.material.navigation.NavigationBarView,%20androidx.navigation.NavController))from`onCreate()`in your main activity class, as shown in the following example:  

### Kotlin

```kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController

    findViewById<BottomNavigationView>(R.id.bottom_nav)
            .setupWithNavController(navController)
}
```

### Java

```java
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    NavHostFragment navHostFragment =
            (NavHostFragment) supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    BottomNavigationView bottomNav = findViewById(R.id.bottom_nav);

    NavigationUI.setupWithNavController(bottomNav, navController);
}
```

With this code in place,`NavigationUI`navigates to the appropriate library graph when the user clicks on a bottom navigation item.

Keep in mind that it's generally bad practice for your app module to have a hard dependency on a specific destination embedded deeply within your feature modules' navigation graph. In most cases, you want your app module to know only about the entry point to any embedded or included navigation graphs (this applies outside of feature modules too). If you need to link to a destination deep within your library's navigation graph, the preferred way to do this is by using a[deep link](https://developer.android.com/guide/navigation/navigation-navigate#uri). Deep linking is also the only way for a library to navigate to a destination in another library's navigation graph.

## Navigating across feature modules

At compile time, independent feature modules cannot see each other, so you can't use IDs to navigate to destinations in other modules. Instead,[use a deep link](https://developer.android.com/guide/navigation/navigation-navigate#uri)to navigate directly to a destination that is associated with an[implicit deep link](https://developer.android.com/guide/navigation/navigation-deep-link#implicit).

Continuing the previous example, imagine you need to navigate from a button in the`:feature:home`module to a destination nested in the`:feature:settings`module. You can do this by adding a deep link to the destination in the settings navigation graph, as shown:  

    <?xml version="1.0" encoding="utf-8"?>
    <navigation xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/settings_nav_graph"
        app:startDestination="@id/settings_fragment_one">

        ...

        <fragment
            android:id="@+id/settings_fragment_two"
            android:name="com.example.google.login.SettingsFragmentTwo"
            android:label="@string/settings_fragment_two" >

            <deepLink
                app:uri="android-app://example.google.app/settings_fragment_two" />
        </fragment>
    </navigation>

Then add the following code to the button's`onClickListener`in the home fragment:  

### Kotlin

```kotlin
button.setOnClickListener {
    val request = NavDeepLinkRequest.Builder
        .fromUri("android-app://example.google.app/settings_fragment_two".toUri())
        .build()
    findNavController().navigate(request)
}
```

### Java

```java
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        NavDeepLinkRequest request = NavDeepLinkRequest.Builder
            .fromUri(Uri.parse("android-app://example.google.app/settings_fragment_two"))
            .build();
        NavHostFragment.findNavController(this).navigate(request);
    }
});
```

Unlike navigating using action or destination IDs, you can navigate to any URI in any graph, even across modules.

When navigating using URI, the back stack is*not* reset. This behavior is unlike[explicit deep link navigation](https://developer.android.com/guide/navigation/navigation-deep-link), where the back stack is replaced when navigating.
| **Note:** Safe Args don't support cross-module navigation, as there isn't direct action to the destination. In the previous example, although a`Directions`class would be generated for the target destination in settings, you aren't able to access the generated class from the classpath of the home module.