Language Detection Middleware
Automatic language detection and URL routing based on user preferences
Middleware automatically detects user language preferences and redirects them to the appropriate localized version of your site. It uses browser settings, geolocation, and user preferences to serve the right language before any content loads.
File location: Place middleware.ts in your project root, at the same level as your app/ directory - not inside it.
Setup
Step 1: Create Dynamic Route
Create a [locale] directory in your app/ folder and move all pages inside it:
Step 2: Add Middleware
Create middleware.ts in your project root:
import { createNextMiddleware } from 'gt-next/middleware';
export default createNextMiddleware();
export const config = {
  // Match all paths except API routes, static files, and Next.js internals
  matcher: ['/((?!api|static|.*\\..*|_next).*)']
};This enables automatic language detection and URL routing with locale prefixes like /en/about, /es/about.
Language Detection
The middleware detects user language preferences in this order:
- URL locale - /es/about→ Spanish
- User cookie - Previous language selection
- Browser headers - Accept-Languageheader
- Default locale - Configured fallback language
The middleware automatically handles browser language detection and cookie persistence without additional configuration.
Localized Paths
Customize URL paths for different languages:
export default createNextMiddleware({
  pathConfig: {
    // English: /en/products, Chinese: /zh/产品
    "/products": {
      "zh": "/产品"
    },
    
    // Dynamic routes: /en/product/123, /zh/产品/123
    "/product/[id]": {
      "zh": "/产品/[id]"
    }
  }
});URL Structure
By default, your default locale will not be prefixed with a locale code:
/about     → /about        (default locale: English)
/about     → /es/about     (Spanish)
/about     → /fr/about     (French)Add Prefix to Default Locale
To prefix all locales including the default:
export default createNextMiddleware({
  prefixDefaultLocale: true
});Result:
/about     → /en/about     (English, with prefix)
/about     → /es/about     (Spanish, with prefix)
/about     → /fr/about     (French, with prefix)Common Issues
Missing Dynamic Route
All pages must be inside [locale]/:
❌ Wrong:
app/
├── page.tsx
└── about/page.tsx
✅ Correct:
app/
└── [locale]/
    ├── page.tsx
    └── about/page.tsxMatcher Configuration
Exclude API routes and static files:
export const config = {
  matcher: ['/((?!api|static|.*\\..*|_next).*)']
};Test your middleware configuration thoroughly - incorrect matchers can cause infinite redirects or break static assets.
Next Steps
- SSG Guide - Static generation with locale routing
- RTL Support - Right-to-left languages
- API References:
How is this guide?

