> For AI agents: the complete documentation index is available at https://rspress.rs/llms.txt, the full documentation bundle is available at https://rspress.rs/llms-full.txt.

# Conventional route

## What is it?

Rspress uses file system routing: each page file path maps directly to a route path, making project routes easy to understand.

For example, a file named `foo.md` in the `docs` directory is routed to `/foo`.

## Mapping rules

Rspress automatically scans the root directory and all subdirectories, and maps file paths to route paths. For example, if you have the following file structure:

```tree
docs
├── foo
│   ├── bar.md
│   └── index.md
├── zoo.md
└── index.md
```

Then `bar.md` is routed to `/foo/bar`, and `/foo/index.md` is routed to `/foo/`.

The specific mapping rules are as follows:

| filepath        | route path | `cleanUrl: false` path |
| --------------- | ---------- | ---------------------- |
| `index.md`      | `/`        | `/index.html`          |
| `/zoo.md`       | `/zoo`     | `/zoo.html`            |
| `/foo/index.md` | `/foo/`    | `/foo/index.html`      |
| `/foo/bar.md`   | `/foo/bar` | `/foo/bar.html`        |

:::warning

Do not create files and folders with the same name, because they cause routing conflicts. For example, the following file structure is not allowed:

```tree
docs
├── foo
│   └── index.md
└── foo.md
```

:::

## TSX routing

In conventional routing, `.tsx` files can also act as route components in addition to `.md(x)` files. By default, the component exported from a `.tsx` file is automatically registered as a route. For example:

```tsx title="foo.tsx"
export default () => {
  return <div>foo</div>;
};
```

To customize the layout, export `frontmatter` and declare the layout type:

```tsx title="foo.tsx"
export const frontmatter = {
  // Declare layout type
  // The custom layout here will not have a sidebar
  pageType: 'custom',
};
```

For the meaning of each `pageType`, see the [API documentation](https://rspress.rs/api/config/config-frontmatter.md#pagetype).

## Custom behavior

If you want to customize the routing behavior, you can use the `route` field in the configuration file. For example:

```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';

export default defineConfig({
  route: {
    // These files will be registered as routes (supports glob pattern)
    include: ['other-dir/**/*'],
    // These files will not be registered as routes (supports glob pattern)
    exclude: ['components/**/*', 'fragments/**/*'],
  },
});
```

## Exclude files starting with `_` by default

In the [docs directory](https://rspress.rs/api/config/config-basic.md#root), MDX fragments or React components must be excluded from routing with [route.exclude](https://rspress.rs/api/config/config-basic.md#routeexclude). For convenience, files starting with "\_" are excluded by default through [route.excludeConvention](https://rspress.rs/api/config/config-basic.md#routeexcludeconvention).

You can also place components in adjacent directories outside the docs directory. For example:

```tree
docs
├── _button.mdx
└── index.mdx
components
└── button.tsx
```


**docs/index.mdx**

```mdx
import ButtonFragment from './_button.mdx';
import Button from '../../components/button';

<ButtonFragment />
<Button />
```


**docs/_button.mdx**

```mdx file="./_button.mdx"
#### button

This is text from MDX

```


**components/button.tsx**

```tsx
const Button = () => <button>This is a button from tsx</button>;
export default Button;
```


It is rendered as:


#### button

This is text from MDX
This is a button from tsx

## Best practices

We recommend placing documentation files in the `docs` directory to keep the project structure clear. Keep non-documentation content, such as custom components and utility functions, outside `docs` when possible. If they must live in `docs`, exclude them with `route.exclude`.

:::tip

If you place custom components or document fragments in the `docs` directory, use `route.exclude`; otherwise, those files are automatically registered as routes and may cause unexpected behavior.

:::

Here is a best practice file structure that includes [MDX fragments and React components](https://rspress.rs/guide/use-mdx/components.md#fragments), [custom themes](https://rspress.rs/guide/basic/custom-theme.md), [conventional routing](https://rspress.rs/guide/basic/conventional-route.md), and [internationalization](https://rspress.rs/guide/basic/i18n.md):

```tree
├── docs
│   ├── components  # React components used in documentation
│   │   └── Example.tsx
│   ├── zh
│   │   ├── fragments   # zh document fragments
│   │   │   └── example.mdx
│   │   └── index.mdx
│   └── en
│       ├── fragments   # en document fragments
│       │   └── example.mdx
│       └── index.mdx
└── theme
    ├── components # React components for theme
    │   └── DocFooter.tsx
    └── index.tsx
```

```ts title="rspress.config.ts"
import { defineConfig } from '@rspress/core';

export default defineConfig({
  route: {
    exclude: ['*/components/**/*', '*/fragments/**/*'], // Files in these directories won't be registered as routes
  },
  lang: 'en',
  locales: [
    {
      lang: 'zh',
      label: '中文',
    },
    {
      lang: 'en',
      label: 'English',
    },
  ],
});
```

```json title="tsconfig.json"
{
  "compilerOptions": {
    "lib": ["DOM", "ESNext"],
    "jsx": "react-jsx",
    "moduleResolution": "bundler",
    "paths": {
      "i18n": ["./i18n.json"],
      "@theme": ["./theme/index.tsx"]
    }
  },
  "include": ["docs", "theme", "rspress.config.ts"],
  "mdx": {
    "checkMdx": true
  }
}
```
