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

# Routing Integration

## Enable Locale Path Prefixes

After setting `localePathRedirect: true`, the plugin takes over language recognition and navigation in the URL. It does four things:

1. **Recognizes the locale prefix in the URL**: When visiting `/zh/detail`, the plugin extracts `zh` from the path as the current language.
2. **Automatically redirects paths without prefixes**: When visiting `/detail`, it first detects the language with the detector. If detection fails, it uses `fallbackLanguage`, then redirects to `/en/detail` or `/zh/detail`.
3. **Synchronizes the URL when switching language**: If the current URL is `/en/detail`, calling `changeLanguage('zh')` automatically changes the URL to `/zh/detail`, instead of only changing i18next's internal language state.
4. **Avoids duplicate path detection**: The plugin automatically removes `path` from the i18next detector `order`, because path language recognition is already handled by the plugin itself.

```ts
// modern.config.ts
i18nPlugin({
  localeDetection: {
    localePathRedirect: true,
    languages: ['zh', 'en'],
    fallbackLanguage: 'en',
  },
});
```

**Result:**

| Visited path | Result                            |
| ------------ | --------------------------------- |
| `/about`     | Redirects to `/en/about`          |
| `/en/about`  | Visits normally, language is `en` |
| `/zh/about`  | Visits normally, language is `zh` |

API and BFF prefixes are skipped automatically, including server API routes, the default `/api` BFF prefix when BFF is configured, and custom `bff.prefix` values. Those routes do not need locale prefixes or `localisedUrls` entries. For additional application paths that should not redirect, use `ignoreRedirectRoutes`. See [Locale Detection -> ignoreRedirectRoutes](/guides/advanced-features/international/locale-detection.md#ignoreredirectroutes).

## Localised URL Paths

`localePathRedirect` only adds and reads locale prefixes by default, for example `/en/about`. Translated path segments are opt-in: `localisedUrls` is enabled only when you provide a non-empty map. Omitting `localisedUrls`, setting it to `true`, setting it to `false`, or passing an empty object keeps prefix-only behavior.

When a non-empty `localisedUrls` map is configured, every localisable route path must define a URL for every configured language. If you add a new language to `languages`, Modern.js will fail route generation until each localised URL entry includes that language too.

`localisedUrls` applies to file-system routes generated for both React Router and TanStack Router projects. Do not configure localised URL entries for API routes, BFF prefixes, or configured `bff.prefix` values; those paths are excluded from locale redirects automatically.

```ts
// modern.config.ts
i18nPlugin({
  localeDetection: {
    localePathRedirect: true,
    languages: ['en', 'cs'],
    fallbackLanguage: 'en',
    localisedUrls: {
      '/terms-of-service': {
        en: '/terms-of-service',
        cs: '/podminky-pouzivani',
      },
      '/products': {
        en: '/products',
        cs: '/produkty',
      },
      '/products/:slug': {
        en: '/products/:slug',
        cs: '/produkty/:slug',
      },
    },
  },
});
```

**Result:**

| Visited path             | Result                                |
| ------------------------ | ------------------------------------- |
| `/terms-of-service`      | Redirects to `/en/terms-of-service`   |
| `/cs/terms-of-service`   | Redirects to `/cs/podminky-pouzivani` |
| `/cs/podminky-pouzivani` | Visits normally, language is `cs`     |

Set `localisedUrls: false` as the escape hatch when a preset, shared config, or generated metadata would otherwise provide a map but this entry should keep locale prefixes without translated path segments.

## Route Configuration

After enabling `localePathRedirect`, add a `[lang]` dynamic parameter in routes to receive the locale prefix.

### File-system Routes

Create a `[lang]` directory under `routes/`:

```
routes/
└── [lang]/
    ├── layout.tsx    <- You can read params.lang here.
    ├── page.tsx
    └── about/
        └── page.tsx
```

Generated route structure:

```
/:lang          -> page.tsx
/:lang/about    -> about/page.tsx
```

If you need to read the current language parameter in a layout or page:

```tsx
// routes/[lang]/layout.tsx
import { Outlet, useParams } from '@modern-js/runtime/router';

export default function Layout() {
  const { lang } = useParams();
  // lang is the language code in the current URL, such as 'en' or 'zh'.
  // Usually you do not need to use it manually. useModernI18n() manages it automatically.
  return <Outlet />;
}
```

### Custom Routes

:::info
Custom routes are only needed when you are not using the Modern.js file-system routing system. File-system routes are recommended for most projects.
:::

If you use a custom route file (`modern.routes.ts`), add the `:lang` parameter manually:

```tsx
// modern.routes.ts
import { Route, Routes, Outlet } from '@modern-js/runtime/router';

export default function App() {
  return (
    <Routes>
      <Route path=":lang" element={<Outlet />}>
        <Route index element={<Home />} />
        <Route path="about" element={<About />} />
      </Route>
    </Routes>
  );
}
```

## I18nLink Component

`I18nLink` is a locale-aware link component. It automatically adds the current locale prefix to the target path, so you do not need to concatenate it manually.

```tsx
import { I18nLink } from '@modern-js/plugin-i18n/runtime';

function Navigation() {
  return (
    <nav>
      <I18nLink to="/">Home</I18nLink>
      <I18nLink to="/about">About</I18nLink>
      <I18nLink to="/contact" replace>Contact</I18nLink>
    </nav>
  );
}
```

**When the current language is `en`:**

```
<I18nLink to="/about">  ->  Actual link: /en/about
<I18nLink to="/">       ->  Actual link: /en
```

**Notes:**

```tsx
// Correct: no need to add the locale prefix manually.
<I18nLink to="/about">About</I18nLink>

// Incorrect: do not add the locale prefix manually, or it becomes /en/en/about.
<I18nLink to="/en/about">About</I18nLink>
```

`I18nLink` uses the active Modern.js router. In React Router projects it renders the React Router `Link`; in TanStack Router projects it navigates through TanStack Router. For the full Props type, see [API Reference](/guides/advanced-features/international/api.md#i18nlink-component).
