Login flows, wizards, or other subflows within your app are usually best represented as nested navigation graphs. By nesting self-contained subnavigation flows in this way, the main flow of your app's UI is easier to comprehend and manage.

In addition, nested graphs are reusable. They also provide a level of encapsulation---destinations outside of the nested graph don't have direct access to any of the destinations within the nested graph. Instead, they should[`navigate()`](https://developer.android.com/reference/androidx/navigation/NavController#navigate(int))to the nested graph itself, where the internal logic can change without affecting the rest of the graph.

## Example

Your app's*top-level*navigation graph should start with the initial destination the user sees when launching the app and should include the destinations that they see as they move about your app.
![](https://developer.android.com/static/images/topic/libraries/architecture/navigation-design-graph-top-level.png)**Figure 1.**A top-level navigation graph.

Using the top-level navigation graph from figure 1 as an example, suppose you wanted to require the user to see the**title_screen** and**register** screens only when the app launches for the first time. Afterwards, the user information is stored, and in subsequent launches of the app, you should take them straight to the**match**screen.

As a best practice, set the**match** screen as the*start destination*of the top-level navigation graph and move the title and register screens into a nested graph, as shown in figure 1:
![](https://developer.android.com/static/images/topic/libraries/architecture/navigation-design-graph-nested.png)**Figure 2.**The top-level navigation graph now contains a nested graph.

When the match screen launches, check to see if there is a registered user. If the user isn't registered, navigate the user to the registration screen.

For more information on conditional navigation scenarios, see[Conditional navigation](https://developer.android.com/guide/navigation/navigation-conditional).

## Compose

To create a nested navigation graph using Compose, use the[`NavGraphBuilder.navigation()`](https://developer.android.com/reference/kotlin/androidx/navigation/NavGraphBuilder#(androidx.navigation.NavGraphBuilder).navigation(kotlin.Any,kotlin.collections.Map,kotlin.Function1))function. You use`navigation()`just like[`NavGraphBuilder.composable()`](https://developer.android.com/reference/kotlin/androidx/navigation/NavGraphBuilder#(androidx.navigation.NavGraphBuilder).composable(kotlin.collections.Map,kotlin.collections.List,kotlin.Function1,kotlin.Function1,kotlin.Function1,kotlin.Function1,kotlin.Function1,kotlin.Function2))and[`NavGraphBuilder.dialog()`](https://developer.android.com/reference/kotlin/androidx/navigation/NavGraphBuilder#(androidx.navigation.NavGraphBuilder).dialog(kotlin.collections.Map,kotlin.Function1))functions when adding destinations to a graph.

The primary difference is that`navigation`creates a nested graph rather than a new destination. You then call`composable()`and`dialog()`within`navigation()`'s lambda to add destinations to the nested graph.

Consider how the following snippet implements the graph in figure 2 using Compose:  

    // Routes
    @Serializable object Title
    @Serializable object Register

    // Route for nested graph
    @Serializable object Game

    // Routes inside nested graph
    @Serializable object Match
    @Serializable object InGame
    @Serializable object ResultsWinner
    @Serializable object GameOver

    NavHost(navController, startDestination = Title) {
       composable<Title> {
           TitleScreen(
               onPlayClicked = { navController.navigate(route = Register) },
               onLeaderboardsClicked = { /* Navigate to leaderboards */ }
           )
       }
       composable<Register> {
           RegisterScreen(
               onSignUpComplete = { navController.navigate(route = Game) }
           )
       }
       navigation<Game>(startDestination = Match) {
           composable<Match> {
               MatchScreen(
                   onStartGame = { navController.navigate(route = InGame) }
               )
           }
           composable<InGame> {
               InGameScreen(
                   onGameWin = { navController.navigate(route = ResultsWinner) },
                   onGameLose = { navController.navigate(route = GameOver) }
               )
           }
           composable<ResultsWinner> {
               ResultsWinnerScreen(
                   onNextMatchClicked = {
                       navController.navigate(route = Match) {
                           popUpTo(route = Match) { inclusive = true }
                       }
                   },
                   onLeaderboardsClicked = { /* Navigate to leaderboards */ }
               )
           }
           composable<GameOver> {
               GameOverScreen(
                   onTryAgainClicked = {
                       navController.navigate(route = Match) {
                           popUpTo(route = Match) { inclusive = true }
                       }
                   }
               )
           }
       }
    }

To[navigate](https://developer.android.com/guide/navigation/use-graph/navigate)directly to a nested destination, use a route type as you would to any other destination. This is because routes are a global concept used to identify destinations that any screen can navigate to:  

    navController.navigate(route = Match)

| **Note:** You should encapsulate the creation of your destinations and navigation events in separate files. For more on this, see[Encapsulate your code](https://developer.android.com/guide/navigation/design/encapsulate)

## XML

When using XML, you can use the Navigation Editor to create your nested graph. To do so follow these steps:

1. In the Navigation Editor, press and hold the**Shift**key, and click the destinations you want to include in the nested graph.
2. Right-click to open the context menu, and select**Move to Nested Graph** \>**New Graph** . The destinations are enclosed in a nested graph. Figure 2 shows a nested graph in the**Navigation Editor**:

   ![](https://developer.android.com/static/images/topic/libraries/architecture/navigation-nestedgraph_2x.png)**Figure 2.**Nested graph in the Navigation Editor
3. Click the nested graph. The following attributes appear in the**Attributes**panel:

   - **Type**, which contains "Nested Graph"
   - **ID**, which contains a system-assigned ID for the nested graph. This ID is used to reference the nested graph from your code.
4. Double-click on the nested graph to show its destinations.

5. Click the**Text** tab to toggle to the XML view. A nested navigation graph has been added to the graph. This navigation graph has its own`navigation`elements along with its own ID and a`startDestination`attribute that points to the first destination in the nested graph:

       <?xml version="1.0" encoding="utf-8"?>
       <navigation xmlns:app="http://schemas.android.com/apk/res-auto"
          xmlns:tools="http://schemas.android.com/tools"
          xmlns:android="http://schemas.android.com/apk/res/android"
          app:startDestination="@id/mainFragment">
          <fragment
              android:id="@+id/mainFragment"
              android:name="com.example.cashdog.cashdog.MainFragment"
              android:label="fragment_main"
              tools:layout="@layout/fragment_main" >
              <action
                  android:id="@+id/action_mainFragment_to_sendMoneyGraph"
                  app:destination="@id/sendMoneyGraph" />
              <action
                  android:id="@+id/action_mainFragment_to_viewBalanceFragment"
                  app:destination="@id/viewBalanceFragment" />
          </fragment>
          <fragment
              android:id="@+id/viewBalanceFragment"
              android:name="com.example.cashdog.cashdog.ViewBalanceFragment"
              android:label="fragment_view_balance"
              tools:layout="@layout/fragment_view_balance" />
          <navigation android:id="@+id/sendMoneyGraph" app:startDestination="@id/chooseRecipient">
              <fragment
                  android:id="@+id/chooseRecipient"
                  android:name="com.example.cashdog.cashdog.ChooseRecipient"
                  android:label="fragment_choose_recipient"
                  tools:layout="@layout/fragment_choose_recipient">
                  <action
                      android:id="@+id/action_chooseRecipient_to_chooseAmountFragment"
                      app:destination="@id/chooseAmountFragment" />
              </fragment>
              <fragment
                  android:id="@+id/chooseAmountFragment"
                  android:name="com.example.cashdog.cashdog.ChooseAmountFragment"
                  android:label="fragment_choose_amount"
                  tools:layout="@layout/fragment_choose_amount" />
          </navigation>
       </navigation>

6. In your code, pass the resource ID of the action connecting the root graph to the nested graph:

### Kotlin

    view.findNavController().navigate(R.id.action_mainFragment_to_sendMoneyGraph)

### Java

    Navigation.findNavController(view).navigate(R.id.action_mainFragment_to_sendMoneyGraph);

1. Back in the**Design** tab, return to the root graph by clicking**Root**.

### Reference other navigation graphs with include

Another way to modularize your graph structure is to[*include*one graph within another](https://developer.android.com/guide/navigation/navigation-nested-graphs#include)using an`<include>`element in the parent navigation graph. This allows the included graph to be defined in a separate module or project altogether, which maximizes reusability.

The following snippet demonstrates how you can use`<include>`:  

    <!-- (root) nav_graph.xml -->
    <?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/fragment">

        <include app:graph="@navigation/included_graph" />

        <fragment
            android:id="@+id/fragment"
            android:name="com.example.myapplication.BlankFragment"
            android:label="Fragment in Root Graph"
            tools:layout="@layout/fragment_blank">
            <action
                android:id="@+id/action_fragment_to_second_graph"
                app:destination="@id/second_graph" />
        </fragment>

        ...
    </navigation>

    <!-- included_graph.xml -->
    <?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/second_graph"
        app:startDestination="@id/includedStart">

        <fragment
            android:id="@+id/includedStart"
            android:name="com.example.myapplication.IncludedStart"
            android:label="fragment_included_start"
            tools:layout="@layout/fragment_included_start" />
    </navigation>