حفظ اختيار لغة المستخدم

استخدام ملف تعريف الارتباط لتذكر الاختيار

المشكلة

يقوم المستخدم باختيار 'الفرنسية' يدويًا على موقع ما. عندما يغلق المتصفح ويكتب لاحقًا عنوان الموقع الرئيسي (مثل 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. التحقق من ملف تعريف الارتباط
  const cookie = request.cookies.get(localeCookieName);
  if (cookie) {
    const locale = cookie.value;
    if (locales.includes(locale)) {
      return locale;
    }
  }

  // 2. التحقق من رأس Accept-Language
  const acceptLang = request.headers.get('Accept-Language');
  if (acceptLang) {
    const bestMatch = parser.pick(locales, acceptLang, {
      loose: true,
    });
    if (bestMatch) {
      return bestMatch;
    }
  }

  // 3. إرجاع اللغة الافتراضية
  return defaultLocale;
}

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;

  // 1. التحقق مما إذا كان الطلب للمسار الجذر
  if (pathname === '/') {
    // الحصول على اللغة المفضلة للمستخدم (من ملف تعريف الارتباط أو الرأس)
    const bestLocale = getPreferredLocale(request);

    // إعادة التوجيه إلى مسار اللغة الأفضل تطابقًا
    request.nextUrl.pathname = `/${bestLocale}`;
    return NextResponse.redirect(request.nextUrl);
  }

  // 2. بالنسبة لجميع المسارات الأخرى، استمر كالمعتاد
  return NextResponse.next();
}

export const config = {
  matcher: [
    // نريد تشغيل هذا على المسار الجذر فقط في الوقت الحالي
    '/',
    // نحتاج أيضًا إلى مطابقة المسارات غير الجذرية للسماح لها بالمرور
    '/((?!api|_next/static|_next/image|favicon.ico).*)',
  ],
};

منطق البرمجيات الوسيطة هذا يعطي الآن الأولوية بشكل صحيح للاختيار الصريح للمستخدم (ملف تعريف الارتباط) على تفضيلهم الضمني (رأس المتصفح) عندما يزورون جذر الموقع.