NEXT_LOCALE cookie is being ignored
Unanswered
Britannia Petite posted this in #help-forum
Britannia PetiteOP
i set the cookie NEXT_LOCALE once a user changes the language on my website
i have a middleware for this and a locale-updater component
i have a middleware for this and a locale-updater component
middleware.ts
import { defaultLocale, locales } from '@/config/i18n' // Import from config
import type { NextRequest } from 'next/server'
import { NextResponse } from 'next/server'
function getLocale(request: NextRequest) {
const pathname = request.nextUrl.pathname
// Check if the pathname already has a locale
const pathnameHasLocale = locales.some(
(locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`,
)
if (pathnameHasLocale) return null
// Check for saved locale in cookies
const savedLocale = request.cookies.get('NEXT_LOCALE')?.value
if (savedLocale && locales.includes(savedLocale as any)) {
return savedLocale
}
// Fallback to default locale
return defaultLocale
}
export function middleware(request: NextRequest) {
const locale = getLocale(request)
if (!locale) return
// Redirect to the same url but with locale
request.nextUrl.pathname = `/${locale}${request.nextUrl.pathname}`
const response = NextResponse.redirect(request.nextUrl)
// Set cookie with better security and longer expiration
response.cookies.set('NEXT_LOCALE', locale, {
path: '/',
sameSite: 'lax', // Changed from 'strict' to 'lax' for better compatibility
secure: true, // Always use secure in production
httpOnly: true, // Prevent JavaScript access
expires: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30 days
})
return response
}
export const config = {
matcher: [
// Skip all internal paths (_next, api, etc)
'/((?!api|_next/static|_next/image|images|favicon.ico|images|dot-texture.svg|map.svg|map2.svg|robots.txt|sitemap.xml|umami.js).*)',
],
}
3 Replies
Britannia PetiteOP
locale-updater.tsx
'use client'
import Cookies from 'js-cookie'
import { usePathname } from 'next/navigation'
import { useEffect } from 'react'
export function LocaleUpdater() {
const pathname = usePathname()
useEffect(() => {
// Extract locale from pathname (e.g., /en/about -> en)
const locale = pathname.split('/')[1]
if (locale) {
// Set cookie with 30 days expiration
Cookies.set('NEXT_LOCALE', locale, {
expires: 30, // 30 days
path: '/',
secure: true,
sameSite: 'lax',
})
}
}, [pathname])
return null
}
any ideas why this doesn't work?
it's being ignored in production, but it works on dev localhost