File-system based router in React Native CLI with react-native-auto-route
Tags: reactnative, tutorial
Published: 2023-12-22 19:05:25

{% youtube zSdXkZiJfMs %}

## Introduction

`react-native-auto-route` is a file-based router for React Native CLI. It is build on top of [React Navigation](https://reactnavigation.org/) and [Expo Router](https://docs.expo.dev/router/introduction/)

It allow you to manage your routes in a simple and intuitive way. When a file is added, removed or renamed, the router is automatically updated. Every screen in your app is automatically deep linkable.

## Installation

### Step 1: Install `react-native-auto-route`:

```sh
yarn add react-native-auto-route
```

### Step 2: Installing peer dependencies:

> If you already have these libraries installed and at the latest version, you can skip this step.

```sh
yarn add react-native-screens react-native-safe-area-context
```

If you're on a Mac and developing for iOS, you need to install the pods (via [Cocoapods](https://cocoapods.org)) to complete the linking.

```sh
npx pod-install ios
```

**react-native-screens** package requires one additional configuration step to properly work on Android devices. 
https://github.com/software-mansion/react-native-screens#android

### Step 3: Add Auto Route plugin

Add `react-native-auto-route/plugin` plugin to your `babel.config.js`.

```js
  module.exports = {
    presets: [
      //...
    ],
    plugins: [
      //...
      "react-native-auto-route/plugin",
    ],
  };
```

### Step 4: Update metro.config.js

Enable `unstable_allowRequireContext` in your `metro.config.js` file.

```js
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');

/**
 * Metro configuration
 * https://facebook.github.io/metro/docs/configuration
 *
 * @type {import('metro-config').MetroConfig}
 */
const config = {
  transformer: {
    unstable_allowRequireContext: true,
  },
};

module.exports = mergeConfig(getDefaultConfig(__dirname), config);
```

### Step 5: Update your `App.tsx` file

Import `react-native-auto-route` and use the `RouterRoot` component. It's similar to `NavigationContainer` from `react-navigation`.

```tsx
import React from 'react';
import RouterRoot from 'react-native-auto-route';

const App = () => {
  return <RouterRoot />;
};

export default App;
```

### Step 6: Create screens

When a file is created in the screens directory (default is: `app`), it will be automatically added to the routes. For example, the following files will create the following routes:

- `app/index.tsx` matches `/`
- `app/home.tsx` matches `/home`
- `app/settings/index.tsx` matches `/settings`
- `app/[user].tsx` matches dynamic paths like `/userId1` or `/userId2`
- `app/(group)/tab1.tsx` matches `/tab1`

> Supported extensions: `.tsx`, `.ts`, `.jsx`, `.js`


You can create dynamic routes by using square brackets in the file name. For example, the following files will create the following routes:

- `app/[user].tsx` matches dynamic paths like `/userId1`
- `app/[user]/[post].tsx` matches dynamic paths like `/userId1/postId1`
- `app/detail/[postId].tsx` matches dynamic paths like `/detail/postId1`
- `app/detail/[...postId].tsx` matches dynamic paths like `/detail/postId1/edit`

Routes with higher specificity will be matched before a dynamic route. For example, `/detail/post` will match `detail/post.tsx` before `detail/[id].tsx`.

Multiple slugs can be matched in a single route by using the rest syntax (...). For example, `app/detail/[...postId].tsx` matches `/detail/postId1/edit`.

You can get params from the route by using the `useParams` hook.


Example: app/[user]/[post].tsx
```tsx
import React from 'react';
import {Text, View} from 'react-native';

export default function UserPost() {
  const params = useParams();
  return (
    <View>
      <Text>Detail: {params.user} - {params.post}</Text>
    </View>
  );
}
```

## References
- Documentation: https://howljs.github.io/react-native-auto-route/docs/getting-started/
- Github: https://github.com/howljs/react-native-auto-route
- Expo Router: https://docs.expo.dev/router/introduction/
- React navigation: https://reactnavigation.org/docs/getting-started/