# General Translation React SDKs (gt-react, gt-next, gt-react-native): App Router middleware
URL: https://generaltranslation.com/en-US/docs/react/nextjs/app-router-middleware.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: How to configure General Translation locale routing for the Next.js App Router.

Configure middleware, a `[locale]` root segment, and a request locale function so App Router requests resolve to the correct localized route.

## Configure the middleware [#middleware]

Create `proxy.ts` in your project root (`middleware.ts` on Next.js 15 and earlier):

```ts title="proxy.ts"
import { createNextMiddleware } from 'gt-next/middleware';

export default createNextMiddleware();

export const config = {
  matcher: ['/((?!api|static|.*\\..*|_next).*)'],
};
```

The middleware detects the locale from the URL, cookie, browser headers, or default locale. It then redirects or rewrites the request to the matching localized route.

## Add the locale route [#locale-route]

Move your App Router pages under `app/[locale]`:

<Files>
  <Folder name="app">
    <Folder name="[locale]">
      <File name="layout.tsx" />
      <File name="page.tsx" />
    </Folder>
  </Folder>
  <File name="getLocale.ts" />
  <File name="proxy.ts" />
</Files>

The route segment receives the locale selected by the middleware. See [`createNextMiddleware`](/docs/react/nextjs/reference/functions/create-next-middleware) for routing options, [localized path aliases](/docs/react/nextjs/reference/functions/create-next-middleware#path-config), and [locale-specific page implementations](/docs/react/nextjs/reference/functions/create-next-middleware#route-overrides).

<Callout type="info">
  **Request-time rendering:** You can keep the root layout at `app/layout.tsx`
  and put only pages below `app/[locale]`. Call
  [`getLocale`](/docs/react/nextjs/reference/functions/get-locale) from the
  root layout; the middleware supplies the request locale, so you do not need
  a custom `getLocale.ts`. Use the request function below when prerendering,
  because middleware does not run during static generation.
</Callout>

## Read the root locale [#root-locale]

Create `getLocale.ts` at your project root. `withGTConfig` detects this file automatically.

```ts title="./getLocale.ts"
import { locale } from 'next/root-params';

export default async function getLocale() {
  return await locale();
}
```

The root parameter supplies the locale without reading request headers or cookies.

<Callout type="info">
  **Next.js 15.2–15.4:** `next/root-params` is available in Next.js 15.5 and
  newer. On 15.2 through 15.4, import `unstable_rootParams` from `next/server`
  and return `(await unstable_rootParams())?.locale` instead. Root params are
  unavailable in any form before 15.2, so resolve the locale from the request
  there.
</Callout>

## Switch locales [#locale-switching]

When a visitor changes locale, `gt-next` stores the choice in a cookie and usually refreshes Server Components with `router.refresh()`.

If the visitor switches to the default locale while the current URL resolves to another locale, the browser reloads so middleware can rewrite the pathname. For example, with an unprefixed default locale, `/fr/about` becomes `/about`.

## Reject unsupported locales [#validate-locales]

By default, an unsupported request locale produces a warning and falls back to `defaultLocale`. For strict locale-prefixed routes, validate the route parameter in `app/[locale]/layout.tsx` and call `notFound()`:

```tsx title="app/[locale]/layout.tsx"
import { isLocaleSupported } from 'gt-next';
import { notFound } from 'next/navigation';

export default async function LocaleLayout({
  children,
  params,
}: {
  children: React.ReactNode;
  params: Promise<{ locale: string }>;
}) {
  const { locale } = await params;

  if (!isLocaleSupported(locale)) {
    notFound();
  }

  return (
    <html lang={locale}>
      <body>{children}</body>
    </html>
  );
}
```

[`isLocaleSupported`](/docs/react/nextjs/reference/functions/is-locale-supported) accepts configured locale aliases and narrows the value to `string`. The middleware does not automatically turn an unknown route segment into a 404.

## Next steps

- /docs/react/nextjs/app-router-static-site-generation
- /docs/react/nextjs/registering-request-locales
- /docs/react/nextjs/cache-components
- /docs/react/nextjs/locale-alias-seo

## Sitemap

See the full [sitemap](https://generaltranslation.com/sitemap.md) for all pages.
