> 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

Granite app makes it easy to handle routing such as screen transitions, history management, and parameter passing. Internally, it [React Navigation](https://reactnavigation.org/)operates based on

{% 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.
{% endhint %}

### Routing example structure

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

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

<details>

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

```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',
  },
});
```

</details>

<details>

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

```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 go to the previous screen.');
    }
  };

  const handlePressNextButton = () => {
    navigation.navigate('/page-c', {
      message: 'Hello!',
      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',
  },
});
```

</details>

<details>

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

```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 start</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',
  },
});
```

</details>

### Page A: Screen navigation

[`useNavigation`](https://reactnavigation.org/docs/use-navigation)is used when handling navigation between screens. [`navigate`](https://reactnavigation.org/docs/navigation-actions/#navigate) With the method, you can pass the destination screen's path and the required data together.

```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',
  },
});
```

#### Key points

* `useNavigation` Use the hook to `navigation` object.
* `navigation.navigate('/page-b')`Calling it navigates to page 'B'.

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

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

```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 go to the previous screen.');
    }
  };

  const handlePressNextButton = () => {
    navigation.navigate('/page-c', {
      message: 'Hello!',
      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',
  },
});
```

#### Key points

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

### Page C: Using passed data

`Route.useParams` The hook is used when retrieving data passed from another screen.

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

```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 start</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',
  },
});
```

#### Key points

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

### Defining screen parameter types

Define Route components like below for each page. Here, `validateParams` option defines the type of parameters that the screen receives.

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

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

Through this, `useNavigate`or `useParams`when using it in other code, type checking lets you clearly know the required path and the data that must be passed. This improves code safety and readability.

***

#### Auto-generated type definitions

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

#### Example of generated file

The automatically generated file looks like this. Since this file is auto-generated, there is no need to edit it manually.

```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>;
  }
}
```

#### Key points

* If you define the type of parameters each screen receives with the `createRoute.validateParams` option, `navigate`and `params` you can get type checking when using it, which lets you write code more safely.
* In development mode, `pages/` Since type definitions are generated automatically when files are added to the directory, there is no need to run a separate command.

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

### Resetting routing state

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

Page A, Page B, and Page C are in order `routes` remain in history, and `index` points to 2, the position of the last navigated page, Page C.

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

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

#### Key points

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

### 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.
