---
title: "Navigation"
description: "Learn more about the Sentry Navigation integration for the Android SDK."
url: https://docs.sentry.io/platforms/android/integrations/navigation/
---

# Navigation | Sentry for Android

The `sentry-android-navigation` library provides [AndroidX Navigation](https://developer.android.com/jetpack/androidx/releases/navigation) support for Sentry using the [SentryNavigationListener](https://github.com/getsentry/sentry-java/blob/524ee49b212c3f2eead20960c3c6825ccdbf8007/sentry-android-navigation/src/main/java/io/sentry/android/navigation/SentryNavigationListener.kt). The source can be found [on GitHub](https://github.com/getsentry/sentry-java/tree/main/sentry-android-navigation/src/main/java/io/sentry/android/navigation).

On this page, we get you up and running with Sentry's Navigation Integration, so that it will automatically add a breadcrumb and start a transaction for each navigation event.

## [Install](https://docs.sentry.io/platforms/android/integrations/navigation.md#install)

Sentry captures data by adding a `NavController.OnDestinationChangedListener`. To add the Navigation integration, install the [Android SDK](https://docs.sentry.io/platforms/android.md), then add the `sentry-android-navigation` dependency using Gradle:

```groovy
implementation 'io.sentry:sentry-android:8.39.1'
implementation 'io.sentry:sentry-android-navigation:8.39.1'
```

## [Configure](https://docs.sentry.io/platforms/android/integrations/navigation.md#configure)

Configuration should happen in the respective lifecycle callbacks, once you retrieve your `NavController` instance:

```kotlin
import androidx.navigation.NavController
import io.sentry.android.navigation.SentryNavigationListener

private val navController = findNavController(R.id.nav_host)
private val sentryNavListener = SentryNavigationListener(
  enableNavigationBreadcrumbs = true, // enabled by default
  enableNavigationTracing = true  // enabled by default
)

override fun onResume() {
  super.onResume()
  navController.addOnDestinationChangedListener(sentryNavListener)
}

override fun onPause() {
  super.onPause()
  navController.removeOnDestinationChangedListener(sentryNavListener)
}
```

By default, the navigation transaction finishes automatically after it reaches the specified [idleTimeout](https://docs.sentry.io/platforms/android/configuration/options.md#idleTimeout) and all of its child spans are finished. You can customize the timeout to your needs.

## [Verify](https://docs.sentry.io/platforms/android/integrations/navigation.md#verify)

This snippet includes a sample `Fragment` with a couple of navigation events and captures an intentional message, so you can test that everything is working as soon as you set it up:

```kotlin
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import io.sentry.android.navigation.SentryNavigationListener
import io.sentry.Sentry

class HomeFragment : Fragment() {

  private val sentryNavListener = SentryNavigationListener()

  override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
  ): View {
    // generated databinding
    return FragmentHomeBinding.inflate(inflater).apply {
        this.sendMessage.setOnClickListener {
            Sentry.captureMessage("Some message.")
        }
        this.openFirstFragment.setOnClickListener {
          findNavController().navigate(R.id.fragment_a)
        }
        this.openSecondFragment.setOnClickListener {
          findNavController().navigate(R.id.fragment_b)
        }
    }.root
  }

  override fun onResume() {
    super.onResume()
    findNavController().addOnDestinationChangedListener(sentryNavListener)
  }

  override fun onPause() {
    super.onPause()
    findNavController().removeOnDestinationChangedListener(sentryNavListener)
  }
}
```

## [Customize the Recorded Breadcrumb/Transaction](https://docs.sentry.io/platforms/android/integrations/navigation.md#customize-the-recorded-breadcrumbtransaction)

By default, the Navigation integration captures route arguments as additional data on breadcrumbs and transactions. In case the arguments contain any PII data, you can strip it out by way of `BeforeBreadcrumbCallback` and `EventProcessor` respectively. To do that, [manually initialize](https://docs.sentry.io/platforms/android/manual-setup.md#configuration-via-sentryoptions) the SDK and add the following snippet:

```kotlin
import io.sentry.EventProcessor
import io.sentry.android.core.SentryAndroid
import io.sentry.SentryOptions.BeforeBreadcrumbCallback
import io.sentry.android.navigation.SentryNavigationListener

SentryAndroid.init(this) { options ->
  options.beforeBreadcrumb = BeforeBreadcrumbCallback { breadcrumb, hint ->
    if (SentryNavigationListener.NAVIGATION_OP == breadcrumb.category) {
      breadcrumb.data.remove("from_arguments")
      breadcrumb.data.remove("to_arguments")
    }
    breadcrumb
  }
  options.addEventProcessor(object : EventProcessor {
    override fun process(transaction: SentryTransaction, hint: Hint): SentryTransaction? {
      if (SentryNavigationListener.NAVIGATION_OP == transaction.contexts.trace.operation) {
        transaction.removeExtra("arguments")
      }
      return transaction
    }
  })
}
```
