> For the complete documentation index, see [llms.txt](https://developers-apps-in-toss.toss.im/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers-apps-in-toss.toss.im/documentation/api-and-sdk-en/react-native/screen-navigation/navigation.md).

# Screen navigation

In the Granite app, you can easily handle routing such as screen transitions, history management, and parameter passing. Internally, it is based on [React Navigation](https://reactnavigation.org/)and works on top of it, so you can use it right away with a familiar API.

{% hint style="info" %}
**WebView Routing**

In a WebView environment, it follows the rules of the web router configured in the project (e.g. React Router) as-is, without any changes.
{% endhint %}

### Routing Example Structure

The routing example consists of a total of 3 pages (`page-a`, `page-b`, `page-c`).

{% code collapsedlinecount="10" %}

```
root
├─── pages
│    ├─── page-a.tsx
│    ├─── page-b.tsx
│    └─── page-c.tsx
└─── src
     └─── ...
```

{% endcode %}

<details>

<summary>`page-a.tsx` source code</summary>

{% code collapsedlinecount="10" %}

```tsx
// page-a.tsx
import { StyleSheet, View, Text, Pressable } from 'react-native';
import { createRoute, useNavigation } from '@granite-js/react-native';

export const Route = createRoute('/page-a', {
  validateParams: (params) => params,
  component: PageA,
});

function PageA() {
  const navigation = useNavigation();

  const handlePress = () => {
    navigation.navigate('/page-b');
  };

  return (
    <View style={[styles.container, { backgroundColor: '#3182f6' }]}>
      <Text style={styles.text}>Page A</Text>
      <Pressable onPress={handlePress}>
        <Text style={styles.buttonLabel}>Go to page B</Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    gap: 16,
    padding: 16,
  },
  text: {
    color: 'white',
    fontSize: 24,
  },
  buttonLabel: {
    color: 'white',
  },
});
```

{% endcode %}

</details>

<details>

<summary>`page-b.tsx` source code</summary>

{% code collapsedlinecount="10" %}

```tsx
// page-b.tsx
import { createRoute, useNavigation } from '@granite-js/react-native';
import { StyleSheet, View, Text, Pressable } from 'react-native';

export const Route = createRoute('/page-b', {
  validateParams: (params) => params,
  component: PageB,
});

function PageB() {
  const navigation = useNavigation();

  // This is a function that goes back to the previous screen.
  const handlePressBackButton = () => {
    if (navigation.canGoBack()) {
      navigation.goBack();
    } else {
      console.warn('Cannot move to the previous screen.');
    }
  };

  const handlePressNextButton = () => {
    navigation.navigate('/page-c', {
      message: 'Hi!',
      date: new Date().getTime(),
    });
  };

  return (
    <View style={[styles.container, { backgroundColor: '#fe9800' }]}>
      <Text style={styles.text}>Page B</Text>
      <Pressable onPress={handlePressBackButton}>
        <Text style={styles.buttonLabel}>Go back</Text>
      </Pressable>
      <Pressable onPress={handlePressNextButton}>
        <Text style={styles.buttonLabel}>Go to page C</Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    gap: 16,
    padding: 16,
  },
  text: {
    color: 'white',
    fontSize: 24,
  },
  buttonLabel: {
    color: 'white',
  },
});
```

{% endcode %}

</details>

<details>

<summary>`page-c.tsx` source code</summary>

{% code collapsedlinecount="10" %}

```tsx
// page-c.tsx
import { useNavigation, createRoute } from '@granite-js/react-native';
import { CommonActions } from '@granite-js/native/@react-navigation/native';
import { StyleSheet, View, Text, Pressable } from 'react-native';

export const Route = createRoute('/page-c', {
  validateParams: (params) => params as { message: string; date: number },
  component: PageC,
});

function PageC() {
  const navigation = useNavigation();
  const params = Route.useParams();

  const handlePressHomeButton = () => {
    navigation.dispatch((state) => {
      return CommonActions.reset({
        ...state,
        index: 0,
        routes: state.routes.filter((route) => route.name === '/page-a'),
      });
    });
  };

  return (
    <View style={[styles.container, { backgroundColor: '#f04452' }]}>
      <Text style={styles.text}>{params.message}</Text>
      <Text style={styles.text}>{params.date}</Text>
      <View style={styles.line} />
      <Text style={styles.text}>Page C</Text>
      <Pressable onPress={handlePressHomeButton}>
        <Text style={styles.buttonLabel}>Go to the beginning</Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    gap: 16,
    padding: 16,
  },
  text: {
    color: 'white',
    fontSize: 24,
  },
  buttonLabel: {
    color: 'white',
  },
});
```

{% endcode %}

</details>

### Page A: Navigate screens

[`useNavigation`](https://reactnavigation.org/docs/use-navigation)is used to handle navigation between screens. [`navigate`](https://reactnavigation.org/docs/navigation-actions/#navigate) You can pass the path of the screen to navigate to along with the required data using the method.

{% code collapsedlinecount="10" %}

```tsx
// page-a.tsx
import { createRoute, useNavigation } from '@granite-js/react-native'; // [!code highlight]
import { StyleSheet, View, Text, Pressable } from 'react-native';

export const Route = createRoute('/page-a', {
  validateParams: (params) => params,
  component: PageA,
});

function PageA() {
  const navigation = useNavigation(); // [!code highlight]
  // [!code highlight:4]
  const handlePress = () => {
    navigation.navigate('/page-b');
  };

  return (
    <View style={[styles.container, { backgroundColor: '#3182f6' }]}>
      <Text style={styles.text}>Page A</Text>
      <Pressable onPress={handlePress}>
        <Text style={styles.buttonLabel}>Go to page B</Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    gap: 16,
    padding: 16,
  },
  text: {
    color: 'white',
    fontSize: 24,
  },
  buttonLabel: {
    color: 'white',
  },
});
```

{% endcode %}

#### Key points

* `useNavigation` Use a hook to `navigation` get the object.
* `navigation.navigate('/page-b')`When you call it, you move to page 'B'.

### Page B: Go back to the previous screen

[`goBack`](https://reactnavigation.org/docs/navigation-actions/#goback) Using the method lets you go back to the previous screen. However, if there is no previous screen history, an error may occur, so [`canGoBack`](https://reactnavigation.org/docs/navigation-prop/#cangoback)you should check first.

{% code collapsedlinecount="10" %}

```tsx
// page-b.tsx
import { createRoute, useNavigation } from '@granite-js/react-native'; // [!code highlight]
import { StyleSheet, View, Text, Pressable } from 'react-native';

export const Route = createRoute('/page-b', {
  validateParams: (params) => params,
  component: PageB,
});

function PageB() {
  const navigation = useNavigation(); // [!code highlight]

  // This is a function that goes back to the previous screen. // [!code highlight:8]
  const handlePressBackButton = () => {
    if (navigation.canGoBack()) {
      navigation.goBack();
    } else {
      console.warn('Cannot move to the previous screen.');
    }
  };

  const handlePressNextButton = () => {
    navigation.navigate('/page-c', {
      message: 'Hi!',
      date: new Date().getTime(),
    });
  };

  return (
    <View style={[styles.container, { backgroundColor: '#fe9800' }]}>
      <Text style={styles.text}>Page B</Text>
      <Pressable onPress={handlePressBackButton}>
        <Text style={styles.buttonLabel}>Go back</Text>
      </Pressable>
      <Pressable onPress={handlePressNextButton}>
        <Text style={styles.buttonLabel}>Go to page C</Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    gap: 16,
    padding: 16,
  },
  text: {
    color: 'white',
    fontSize: 24,
  },
  buttonLabel: {
    color: 'white',
  },
});
```

{% endcode %}

#### Key points

* `canGoBack()`to check whether there is a previous screen, and if there is, `goBack()`is called.
* `navigate('/page-c', { message: 'Hi!', date: new Date().getTime() })`to move to page 'C' while passing data.

### Page C: Using passed data

`Route.useParams` The hook is used to retrieve data passed from another screen.

At this time, `createRoute.validateParams` By configuring the option, you can access the passed data with type validation (Type-Safe). This helps prevent errors caused by incorrect data formats.

{% code collapsedlinecount="10" %}

```tsx
// page-c.tsx
import { createRoute, useNavigation } from '@granite-js/react-native'; // [!code highlight]
import { CommonActions } from '@granite-js/native/@react-navigation/native';
import { StyleSheet, View, Text, Pressable } from 'react-native';

// [!code highlight:5]
export const Route = createRoute('/page-c', {
  validateParams: (params) => params as { message: string; date: number },
  component: PageC,
});

function PageC() {
  const navigation = useNavigation();
  const params = Route.useParams(); // [!code highlight:7]
  // Or you can use it like below.
  // import { useParams } from '@granite-js/react-native';
  //
  // const params = useParams({
  //   from: '/page-b',
  // });

  const handlePressHomeButton = () => {
    navigation.dispatch((state) => {
      return CommonActions.reset({
        ...state,
        index: 0,
        routes: state.routes.filter((route) => route.name === '/page-a'),
      });
    });
  };

  return (
    <View style={[styles.container, { backgroundColor: '#f04452' }]}>
      <Text style={styles.text}>{params.message}</Text> // [!code highlight]
      <Text style={styles.text}>{params.date}</Text> // [!code highlight]
      <View style={styles.line} />
      <Text style={styles.text}>Page C</Text>
      <Pressable onPress={handlePressHomeButton}>
        <Text style={styles.buttonLabel}>Go to the beginning</Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    gap: 16,
    padding: 16,
  },
  text: {
    color: 'white',
    fontSize: 24,
  },
  buttonLabel: {
    color: 'white',
  },
});
```

{% endcode %}

#### Key points

* `Route.useParams` Using the hook, you can access data (parameters) passed in the URL.
* `createRoute.validateParams` By setting the option, you can use the data safely while validating its type (Type-Safe).

### Defining screen parameter types

Define a Route component like the one below for each page. Here, `validateParams` option defines the type of parameters that can be received on that screen.

{% code collapsedlinecount="10" %}

```tsx
export const Route = createRoute('/page-c', {
  validateParams: (params) => params as { message: string; date: number }, // [!code highlight]
  component: PageC,
});
```

{% endcode %}

In the code above, `validateParams`is `message`and `date`define parameters that include these two fields as a type.

This allows other code to `useNavigate`or `useParams`use type checking to clearly know the required path and the data that must be passed. This improves code safety and readability.

***

#### Automatically generate type definitions

In development mode, `pages/` when a file is added to the directory, type definitions are generated automatically, so you don't need to run a separate command.

#### Example of a generated file

The automatically generated file looks like this. Since this file is auto-generated, you don't need to edit it manually.

{% code collapsedlinecount="10" %}

```tsx
// src/router.gen.ts

/* eslint-disable */
// This file is auto-generated by @granite-js/react-native. DO NOT EDIT.
import { Route as _AboutRoute } from '../pages/about';
import { Route as _IndexRoute } from '../pages/';

declare module '@granite-js/react-native' {
  interface RegisterScreen {
    '/about': ReturnType<typeof _AboutRoute.useParams>;
    '/': ReturnType<typeof _IndexRoute.useParams>;
  }
}
```

{% endcode %}

#### Key points

* The type of parameters received on each screen `createRoute.validateParams` If you define it with the option, `navigate`and `params` you can get type checking when using it, which allows you to write code more safely.
* In development mode, `pages/` Since type definitions are generated automatically when a file is added to the directory, you don't need to run a separate command.

Using React Navigation like this makes it easy to handle navigation between screens, and you can implement various UX features through passing data or manipulating history. Also, when used together with TypeScript, you can write safe and robust code.

### Reset routing state

The state immediately after moving in the order Page A → Page B → Page C can be represented as shown in the figure below.

Page A, Page B, and Page C in order `routes` remain in history, `index` value points to 2, the position of Page C, which was moved to last.

`reset`Using it, you can reset the navigation history. For example, after moving to 'Page A → B → C', if you want to return to 'Page A' and delete the B and C history, [`CommonActions.reset`](https://reactnavigation.org/docs/navigation-actions/#reset)Use it.

{% code collapsedlinecount="10" %}

```tsx
navigation.dispatch(
  CommonActions.reset({
    index: 0,
    routes: [{ name: '/page-a' }],
  }),
);
```

{% endcode %}

#### Key points

* `CommonActions.reset`can keep only a specific screen in history and delete the history of the others.

### Reference

* [React Navigation Official Documentation](https://reactnavigation.org/)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developers-apps-in-toss.toss.im/documentation/api-and-sdk-en/react-native/screen-navigation/navigation.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
