الاحتفاظ باختيار لغة المستخدم
استخدام ملف تعريف الارتباط لتذكر الاختيار
المشكلة
يختار المستخدم يدويًا 'الفرنسية' على موقع ما. عندما يغلق المتصفح ويكتب لاحقًا عنوان الموقع الرئيسي (على سبيل المثال، example.com)، يعود التطبيق إلى لغته الافتراضية (على سبيل المثال، الإنجليزية) أو اللغة المكتشفة تلقائيًا. يجبر هذا الفشل في تذكر اختيارهم المستخدم على البحث عن مبدل اللغة وإعادة تحديد لغته في كل مرة يبدأ فيها جلسة جديدة.
الحل
عندما يختار المستخدم لغة، قم بتخزين هذا الاختيار في ملف تعريف ارتباط. في البرمجية الوسيطة، عندما يزور المستخدم المسار الجذر (/)، تحقق من ملف تعريف الارتباط هذا قبل التحقق من رأس Accept-Language. إذا تم العثور على ملف تعريف ارتباط صالح، قم بإعادة توجيه المستخدم إلى الجذر الخاص باللغة المختارة (على سبيل المثال، /fr)، متجاوزًا أي إعداد افتراضي للمتصفح.
الخطوات
1. تحديد إعدادات اللغة
أنشئ ملف إعدادات مركزي لتخزين اللغات المدعومة، واللغة الافتراضية، واسم ملف تعريف الارتباط الذي ستستخدمه لتخزين تفضيل المستخدم.
// i18n.config.ts
export const locales = ['en', 'es', 'fr'];
export const defaultLocale = 'en';
export const localeCookieName = 'NEXT_LOCALE';
2. تثبيت محلل اللغة
لا تزال بحاجة إلى محلل لرأس Accept-Language، والذي سيتم استخدامه كبديل احتياطي إذا لم يتم تعيين ملف تعريف ارتباط.
npm install accept-language-parser
3. إنشاء البرمجية الوسيطة
أنشئ ملف middleware.ts في جذر مشروعك. ستتحقق هذه البرمجية الوسيطة من ملف تعريف الارتباط NEXT_LOCALE أولاً. إذا لم يتم العثور عليه، فسيتم الرجوع إلى التحقق من رأس Accept-Language. سيتم تطبيق هذا المنطق فقط على الطلبات الخاصة بالمسار الجذر (/).
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import parser from 'accept-language-parser';
import {
locales,
defaultLocale,
localeCookieName,
} from './i18n.config';
function getPreferredLocale(request: NextRequest) {
// 1. Check for the cookie
const cookie = request.cookies.get(localeCookieName);
if (cookie) {
const locale = cookie.value;
if (locales.includes(locale)) {
return locale;
}
}
// 2. Check the Accept-Language header
const acceptLang = request.headers.get('Accept-Language');
if (acceptLang) {
const bestMatch = parser.pick(locales, acceptLang, {
loose: true,
});
if (bestMatch) {
return bestMatch;
}
}
// 3. Return the default
return defaultLocale;
}
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
// 1. Check if the request is for the root path
if (pathname === '/') {
// Get the user's preferred language (from cookie or header)
const bestLocale = getPreferredLocale(request);
// Redirect to the best-matched language path
request.nextUrl.pathname = `/${bestLocale}`;
return NextResponse.redirect(request.nextUrl);
}
// 2. For all other paths, continue as normal
return NextResponse.next();
}
export const config = {
matcher: [
// We only want to run this on the root path for now
'/',
// We also need to match non-root paths to let them pass
'/((?!api|_next/static|_next/image|favicon.ico).*)',
],
};
منطق هذه الوسيطة يعطي الآن الأولوية بشكل صحيح لاختيار المستخدم الصريح (ملف تعريف الارتباط) على تفضيله الضمني (رأس المتصفح) عندما يزور الجذر الرئيسي للموقع.