# Screen Tracking

Track which screens your users view most — automatic for Expo Router, one function call for React Navigation and anything else.

Screen tracking powers the dashboard's **Screen Usage** card: your most-viewed screens, ranked, with per-day trends. Enable it with `analytics: { screens: true }` (see [Analytics Setup](/docs/analytics/setup)), then choose one of the two tracking modes below.

## Expo Router: one line in the root layout

Expo Router exposes the current route through hooks, so the SDK ships an automatic tracker — add it to your root layout and every route change is tracked:

```jsx
import { Slot } from "expo-router";
import { useNativeNotifyScreenTracking } from "native-notify";

export default function RootLayout() {
  useNativeNotifyScreenTracking();

  return <Slot />;
}
```

This uses Expo Router's documented screen-tracking pattern (`usePathname()` from the root layout), so it catches every navigation — pushes, replaces, back gestures, and deep links.

## Manual tracking: `trackScreen(name)`

For React Navigation, bare React Native, or when you want to control the names yourself, call `trackScreen()` wherever you already know the active screen:

```js
import { trackScreen } from "native-notify";

trackScreen("Home");
trackScreen("Settings");
trackScreen(`/products/${productId}`);
```

With React Navigation, the [screen-tracking guide](https://reactnavigation.org/docs/screen-tracking/) shows where to hook navigation state changes — replace its `Analytics.setCurrentScreen(currentRouteName)` call with `trackScreen(currentRouteName)`:

```jsx
<NavigationContainer
  onStateChange={async () => {
    const previousRouteName = routeNameRef.current;
    const currentRouteName = navigationRef.current?.getCurrentRoute()?.name;

    if (currentRouteName && previousRouteName !== currentRouteName) {
      trackScreen(currentRouteName);
    }
    routeNameRef.current = currentRouteName;
  }}
  ref={navigationRef}
>
  {/* ... */}
</NavigationContainer>
```

`useNativeNotifyScreenTracking()` also accepts a reader function for any other navigator:

```jsx
useNativeNotifyScreenTracking(() => currentRouteName);
```

## Naming screens

- Use short, stable names — they become the ranking rows on your dashboard. Route paths like `/products/123` are fine, but consider deduplicating parameters (`/products/[id]`) if the list gets long.
- Names are trimmed and capped at 120 characters.
- The first screen after an app launch is a normal view like any other; there is no required "Home" convention.

## How reporting works

- Views are **batched**: a few events are combined into one request, flushed about two seconds later (and immediately when the app backgrounds).
- The same screen reported twice in a row (a re-render, a remount, a tab switch straight back) counts **once**.
- **Unique views** count distinct devices: with `deviceId` enabled they survive reinstalls and token rotation; otherwise the Expo push token is used.
- Reporting is best-effort — screen tracking never blocks or breaks navigation.

Data shows up on the dashboard within seconds of each view.
