App Directory: Override browser locale by setting NEXT_LOCALE? ðŸŒ
Unanswered
American Wirehair posted this in #help-forum
American WirehairOP
Hi,
I'm using the new app directory based routing, and have set up a pretty standard middleware to handle i18n routing. This works. But with the page based i18n handeling I could set the NEXT_LOCALE cookie to let users override the language settings. This does not work out of the box it looks like. How would I achieve this using app directory?
I'm using the new app directory based routing, and have set up a pretty standard middleware to handle i18n routing. This works. But with the page based i18n handeling I could set the NEXT_LOCALE cookie to let users override the language settings. This does not work out of the box it looks like. How would I achieve this using app directory?
1 Reply
American WirehairOP
Here is my
middleware.ts.import { NextResponse } from "next/server"
import type { NextRequest } from "next/server"
import { cookies } from "next/headers"
import { i18n } from "./i18n-config"
import { match as matchLocale } from "@formatjs/intl-localematcher"
import Negotiator from "negotiator"
function getLocale(request: NextRequest): string | undefined {
const negotiatorHeaders: Record<string, string> = {}
request.headers.forEach((value, key) => (negotiatorHeaders[key] = value))
// @ts-ignore locales are readonly
const locales: string[] = i18n.locales
const languages = new Negotiator({ headers: negotiatorHeaders }).languages(
locales
)
const locale = matchLocale(languages, locales, i18n.defaultLocale)
return locale
}
export function middleware(request: NextRequest) {
const pathname = request.nextUrl.pathname
const cookieStore = cookies()
const cookieLocale = cookieStore.get("NEXT_LOCALE")?.value
if (
[
"/logo.svg",
"/logo-white.svg",
"/favicon.ico",
// Your other files in `public`
].includes(pathname)
)
return
const pathnameIsMissingLocale = i18n.locales.every(
(locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}`
)
if (pathnameIsMissingLocale) {
const locale = getLocale(request)
return NextResponse.redirect(
new URL(
`/${locale}${pathname.startsWith("/") ? "" : "/"}${pathname}`,
request.url
)
)
}
}
export const config = {
matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
}