كيفية اكتشاف تفضيلات لغة المستخدم في TanStack Start v1
إعادة التوجيه التلقائي بناءً على تفضيلات المتصفح
المشكلة
تُرسل متصفحات الويب رأس Accept-Language مع كل طلب HTTP، مما يشير إلى اللغات المفضلة للمستخدم حسب الأولوية. يوفر هذا الرأس معلومات قيمة حول اللغة التي يشعر المستخدم بأكبر قدر من الراحة معها، ومع ذلك تتجاهله العديد من التطبيقات تمامًا. بدلاً من ذلك، تعرض لغة افتراضية - عادةً الإنجليزية - لجميع الزوار، بغض النظر عن تفضيلاتهم الفعلية. يجب على المستخدمين بعد ذلك البحث يدويًا عن مبدل اللغة، مما يخلق احتكاكًا غير ضروري عندما يكون لدى التطبيق بالفعل المعلومات اللازمة لاتخاذ خيار أولي أفضل.
هذه الفرصة الضائعة للتخصيص محبطة بشكل خاص للمتحدثين بغير الإنجليزية الذين قاموا بتكوين تفضيلات لغة متصفحهم بشكل صريح. والنتيجة هي انطباع أول متدهور وخطوات إضافية قبل أن يتمكن المستخدمون من التفاعل مع المحتوى بلغتهم المفضلة.
الحل
اعترض الطلبات إلى المسار الجذر وافحص رأس Accept-Language لتحديد اللغة المفضلة للمستخدم. قم بتحليل الرأس لاستخراج اللغة ذات الأولوية الأعلى التي يدعمها تطبيقك. إذا تم العثور على تطابق، أعد توجيه المستخدم إلى المسار المترجم المناسب. إذا لم يتم العثور على لغة مدعومة في الرأس، أعد التوجيه إلى لغة افتراضية احتياطية.
يحترم هذا النهج تفضيلات المستخدم تلقائيًا مع الحفاظ على بنية URL واضحة حيث يكون لكل لغة بادئة مسار خاصة بها. تحدث إعادة التوجيه من جانب الخادم قبل عرض الصفحة، مما يضمن وصول المستخدمين مباشرة إلى المحتوى بلغتهم المفضلة دون رؤية وميض للغة الخاطئة.
الخطوات
1. إنشاء دالة مساعدة لتحليل رأس Accept-Language
يحتوي رأس Accept-Language على رموز اللغات مع قيم جودة اختيارية تشير إلى ترتيب الأفضلية. قم ببناء محلل يستخرج هذه اللغات، ويرتبها حسب الأولوية، ويجد أول تطابق من قائمة اللغات المدعومة لديك.
export function parseAcceptLanguage(
header: string | null,
supportedLocales: string[],
): string | null {
if (!header) {
return null;
}
const languages = header
.split(",")
.map((lang) => {
const [code, qValue] = lang.trim().split(";q=");
const quality = qValue ? parseFloat(qValue) : 1.0;
return { code: code.toLowerCase(), quality };
})
.sort((a, b) => b.quality - a.quality);
for (const { code } of languages) {
const exactMatch = supportedLocales.find(
(locale) => locale.toLowerCase() === code,
);
if (exactMatch) {
return exactMatch;
}
const baseCode = code.split("-")[0];
const baseMatch = supportedLocales.find((locale) =>
locale.toLowerCase().startsWith(baseCode),
);
if (baseMatch) {
return baseMatch;
}
}
return null;
}
تقوم هذه الدالة بتقسيم الرأس بالفواصل، واستخراج قيم الجودة، والترتيب حسب الأفضلية، والتحقق من التطابقات الدقيقة وتطابقات اللغة الأساسية مقابل الإعدادات المحلية المدعومة لديك.
2. حدد الإعدادات المحلية المدعومة
أنشئ تكويناً يسرد جميع اللغات التي يدعمها تطبيقك ويحدد أي منها سيتم استخدامه كخيار احتياطي افتراضي.
export const SUPPORTED_LOCALES = ["en", "fr", "de", "es", "ja"];
export const DEFAULT_LOCALE = "en";
تعمل هذه الثوابت على مركزة تكوين اللغة لديك وتسهل إضافة أو إزالة اللغات المدعومة مع نمو تطبيقك.
3. أنشئ معالج مسار خادم للمسار الجذر
أضف معالج GET من جانب الخادم إلى مسار الفهرس الخاص بك والذي يقرأ رأس Accept-Language، ويحدد أفضل إعداد محلي، ويعيد توجيه المستخدم إلى المسار الخاص باللغة المناسبة.
import { createFileRoute, redirect } from "@tanstack/react-router";
import { getRequestHeaders } from "@tanstack/react-start/server";
export const Route = createFileRoute("/")({
server: {
handlers: {
GET: async () => {
const headers = getRequestHeaders();
const acceptLanguage = headers.get("accept-language");
const preferredLocale = parseAcceptLanguage(
acceptLanguage,
SUPPORTED_LOCALES,
);
const targetLocale = preferredLocale || DEFAULT_LOCALE;
throw redirect({
to: `/${targetLocale}`,
statusCode: 302,
});
},
},
},
});
يعمل هذا المعالج على الخادم عندما يزور المستخدم المسار الجذر، ويفحص تفضيلات اللغة الخاصة به، ويعيد توجيهه فوراً إلى مسار الإعداد المحلي الأفضل تطابقاً قبل تنفيذ أي كود من جانب العميل.
4. استورد الدالة المساعدة
تأكد من توفر المساعد parse في ملف المسار الخاص بك عن طريق استيراده في الأعلى جنباً إلى جنب مع تكوين الإعداد المحلي الخاص بك.
import { createFileRoute, redirect } from "@tanstack/react-router";
import { getRequestHeaders } from "@tanstack/react-start/server";
import {
parseAcceptLanguage,
SUPPORTED_LOCALES,
DEFAULT_LOCALE,
} from "../lib/locale";
ضع الدالة parseAcceptLanguage وثوابت الإعداد المحلي في وحدة مشتركة بحيث يمكن إعادة استخدامها عبر تطبيقك إذا لزم الأمر.