تبديل اللغة
قم بتنفيذ أدوات تبديل اللغة للسماح للمستخدمين بتغيير اللغة المفضلة لديهم.
التنفيذ الأساسي
استخدم خطاف useLingoContext للحصول على اللغة الحالية ودالة لتغييرها:
"use client"; // For Next.js
import { useLingoContext } from "@lingo.dev/compiler/react";
export function LanguageSwitcher() {
const { locale, setLocale } = useLingoContext();
return (
<select value={locale} onChange={(e) => setLocale(e.target.value)}>
<option value="en">English</option>
<option value="es">Español</option>
<option value="de">Deutsch</option>
<option value="fr">Français</option>
</select>
);
}
عند استدعاء setLocale():
- يتم حفظ اللغة الجديدة (عبر محلل مخصص أو ملف تعريف ارتباط افتراضي)
- يتم إعادة تحميل الصفحة لتطبيق اللغة الجديدة
واجهة مستخدم مخصصة
قائمة منسدلة مع الأعلام
"use client";
import { useLingoContext } from "@lingo.dev/compiler/react";
const locales = [
{ code: "en", name: "English", flag: "🇺🇸" },
{ code: "es", name: "Español", flag: "🇪🇸" },
{ code: "de", name: "Deutsch", flag: "🇩🇪" },
{ code: "fr", name: "Français", flag: "🇫🇷" },
];
export function LanguageSwitcher() {
const { locale: currentLocale, setLocale } = useLingoContext();
return (
<div className="relative">
<select
value={currentLocale}
onChange={(e) => setLocale(e.target.value)}
className="px-4 py-2 border rounded-md"
>
{locales.map((locale) => (
<option key={locale.code} value={locale.code}>
{locale.flag} {locale.name}
</option>
))}
</select>
</div>
);
}
مجموعة أزرار
"use client";
import { useLingoContext } from "@lingo.dev/compiler/react";
export function LanguageSwitcher() {
const { locale, setLocale } = useLingoContext();
const locales = ["en", "es", "de", "fr"];
return (
<div className="flex gap-2">
{locales.map((loc) => (
<button
key={loc}
onClick={() => setLocale(loc)}
className={`px-3 py-1 rounded ${
locale === loc ? "bg-blue-500 text-white" : "bg-gray-200"
}`}
>
{loc.toUpperCase()}
</button>
))}
</div>
);
}
قائمة منسدلة
"use client";
import { useState } from "react";
import { useLingoContext } from "@lingo.dev/compiler/react";
export function LanguageSwitcher() {
const { locale, setLocale } = useLingoContext();
const [isOpen, setIsOpen] = useState(false);
const locales = [
{ code: "en", name: "English" },
{ code: "es", name: "Español" },
{ code: "de", name: "Deutsch" },
{ code: "fr", name: "Français" },
];
const currentLocaleName = locales.find((l) => l.code === locale)?.name;
return (
<div className="relative">
<button
onClick={() => setIsOpen(!isOpen)}
className="px-4 py-2 border rounded-md flex items-center gap-2"
>
<span>{currentLocaleName}</span>
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
</svg>
</button>
{isOpen && (
<div className="absolute top-full mt-2 bg-white border rounded-md shadow-lg">
{locales.map((loc) => (
<button
key={loc.code}
onClick={() => {
setLocale(loc.code);
setIsOpen(false);
}}
className={`block w-full text-left px-4 py-2 hover:bg-gray-100 ${
locale === loc.code ? "bg-blue-50" : ""
}`}
>
{loc.name}
</button>
))}
</div>
)}
</div>
);
}
الاستمرارية
بشكل افتراضي، يستخدم setLocale() استمرارية اللغة المكوّنة لديك (ملف تعريف الارتباط بشكل افتراضي).
استمرارية مخصصة
قم بتنفيذ استمرارية مخصصة عبر محللات اللغة المخصصة:
// .lingo/locale-resolver.client.ts
export function persistLocale(locale: string): void {
// Custom logic: localStorage, URL params, API call, etc.
localStorage.setItem("locale", locale);
window.location.reload();
}
يستدعي setLocale() تلقائيًا دالة persistLocale() الخاصة بك.
تجنب إعادة تحميل الصفحة
بشكل افتراضي، يقوم setLocale() بإعادة تحميل الصفحة لتطبيق اللغة الجديدة. لتجنب إعادة التحميل:
- استخدم إدارة الحالة من جانب العميل
- قم بتحميل الترجمات مسبقًا لجميع اللغات
- قم بتبديل الترجمات دون إعادة تحميل الصفحة
ملاحظة: يتطلب هذا تنفيذًا مخصصًا—السلوك الافتراضي للمترجم يعيد تحميل الصفحة من أجل البساطة.
تبديل اللغة المستند إلى عنوان URL
للتوجيه المستند إلى عنوان URL (/en/about، /es/about):
"use client";
import { useRouter, usePathname } from "next/navigation";
export function LanguageSwitcher() {
const router = useRouter();
const pathname = usePathname();
// Extract current locale from path: /es/about → es
const currentLocale = pathname.split("/")[1];
function switchLocale(newLocale: string) {
// Replace locale in path: /es/about → /de/about
const newPath = pathname.replace(`/${currentLocale}`, `/${newLocale}`);
router.push(newPath);
}
return (
<select value={currentLocale} onChange={(e) => switchLocale(e.target.value)}>
<option value="en">English</option>
<option value="es">Español</option>
<option value="de">Deutsch</option>
</select>
);
}
التبديل المعتمد على النطاق الفرعي
للتوجيه المعتمد على النطاق الفرعي (es.example.com):
"use client";
export function LanguageSwitcher() {
const currentLocale = window.location.hostname.split(".")[0];
function switchLocale(newLocale: string) {
const host = window.location.hostname;
const domain = host.split(".").slice(1).join(".");
const newHost = `${newLocale}.${domain}`;
window.location.href = `${window.location.protocol}//${newHost}${window.location.pathname}`;
}
return (
<select value={currentLocale} onChange={(e) => switchLocale(e.target.value)}>
<option value="en">English</option>
<option value="es">Español</option>
<option value="de">Deutsch</option>
</select>
);
}
أسماء اللغات الأصلية
اعرض أسماء اللغات بلغتها الأصلية لتحسين تجربة المستخدم:
const locales = [
{ code: "en", name: "English" },
{ code: "es", name: "Español" },
{ code: "de", name: "Deutsch" },
{ code: "fr", name: "Français" },
{ code: "ja", name: "日本語" },
{ code: "zh", name: "中文" },
{ code: "ar", name: "العربية" },
{ code: "ru", name: "Русский" },
];
إمكانية الوصول
اجعل مبدل اللغة الخاص بك قابلاً للوصول:
const { locale, setLocale } = useLingoContext();
<div role="group" aria-label="Language selector">
<label htmlFor="language-select" className="sr-only">
Choose language
</label>
<select
id="language-select"
value={locale}
onChange={(e) => setLocale(e.target.value)}
aria-label="Select language"
>
{locales.map((loc) => (
<option key={loc.code} value={loc.code}>
{loc.name}
</option>
))}
</select>
</div>
الأنماط الشائعة
التكامل مع شريط التنقل
export function Navbar() {
return (
<nav className="flex items-center justify-between p-4">
<Logo />
<div className="flex items-center gap-4">
<NavLinks />
<LanguageSwitcher />
</div>
</nav>
);
}
التكامل مع التذييل
export function Footer() {
return (
<footer className="p-4 border-t">
<div className="flex justify-between items-center">
<p>© 2024 Your Company</p>
<LanguageSwitcher />
</div>
</footer>
);
}
القائمة المحمولة
export function MobileMenu() {
return (
<div className="mobile-menu">
<NavLinks />
<div className="border-t pt-4 mt-4">
<p className="text-sm text-gray-500 mb-2">Language</p>
<LanguageSwitcher />
</div>
</div>
);
}
الاختبار
اختبر تبديل اللغة في بيئة التطوير:
- أضف مكون مبدل اللغة
- شغّل خادم التطوير
- انقر للتبديل بين اللغات
- تحقق من إعادة تحميل الصفحة باللغة الجديدة
- تأكد من تحديث الترجمات
مع تفعيل المترجم الزائف، سترى ترجمات وهمية فوراً.
الأسئلة الشائعة
لماذا يتم إعادة تحميل الصفحة؟ يقوم المترجم بإعادة تحميل الصفحة لتطبيق اللغة الجديدة. هذا يضمن تحديث جميع مكونات الخادم والبيانات الوصفية بشكل صحيح.
هل يمكنني تجنب إعادة التحميل؟ نعم، لكن يتطلب تنفيذاً مخصصاً. قم بتحميل جميع الترجمات مسبقاً وإدارة الحالة من جانب العميل يدوياً.
هل أحتاج إلى تغليف LanguageSwitcher في Suspense؟
لا. useLingoContext متزامن—لا حاجة لـ suspense.
هل يمكنني اكتشاف لغة متصفح المستخدم تلقائيًا؟ نعم. قم بالتنفيذ في محللات اللغة المخصصة:
export function getClientLocale(): string {
return navigator.language.split("-")[0] || "en";
}
هل يجب أن أعرض جميع اللغات المدعومة أم بعضها فقط؟ اعرض الكل في قائمة منسدلة. إذا كانت هناك لغات كثيرة، قم بتجميعها حسب المنطقة أو استخدم واجهة بحث/تصفية.
الخطوات التالية
- محللات اللغة المخصصة — تخصيص الاستمرارية
- تكامل إطار العمل — أنماط التوجيه الخاصة بإطار العمل
- أفضل الممارسات — توصيات تجربة المستخدم لتبديل اللغة