كيفية بناء مكون تبديل اللغة في TanStack Start v1

تبديل اللغات مع البقاء على نفس الصفحة

المشكلة

عندما يقوم المستخدمون بتبديل اللغات في تطبيق متعدد اللغات، فإنهم يتوقعون البقاء على نفس الصفحة لعرض نفس المحتوى باللغة الجديدة. يتعامل مبدل اللغة المُنفذ بشكل سيئ مع اختيار اللغة كتنقل إلى وجهة مختلفة، وغالباً ما يعيد توجيه المستخدمين إلى الصفحة الرئيسية ويفقدهم مكانهم بالكامل. هذا يقطع تدفق المستخدم ويخلق إحباطاً، خاصة عندما يكون المستخدمون في عمق سير عمل أو يشاهدون محتوى محدداً. التحدي هو بناء مبدل يغير فقط جزء اللغة من عنوان URL مع الحفاظ على بقية المسار ومعاملات البحث والهاش.

الحل

قم ببناء مكون تبديل لغة يقرأ مسار عنوان URL الحالي وينشئ روابط لكل لغة متاحة عن طريق استبدال جزء اللغة في المسار. استخرج اللغة الحالية من بنية عنوان URL، ثم أنشئ مسارات جديدة للغات الأخرى المدعومة عن طريق استبدال جزء اللغة مع الحفاظ على جميع أجزاء عنوان URL الأخرى سليمة. استخدم هذه المسارات لعرض روابط تسمح للمستخدمين بتبديل اللغات دون فقدان سياق صفحتهم الحالية.

الخطوات

1. تحديد اللغات المدعومة

أنشئ ملف تكوين يسرد جميع اللغات التي يدعمها تطبيقك ويحدد اللغة الافتراضية.

export const locales = ["en", "fr", "es", "de"] as const;

export type Locale = (typeof locales)[number];

export const defaultLocale: Locale = "en";

يعمل هذا التكوين كمصدر وحيد للحقيقة للغات المتاحة وسيتم استخدامه لإنشاء روابط المبدل.

2. إنشاء دالة مساعدة لاستخراج اللغة الحالية من المسار

اكتب دالة مساعدة تحلل المسار وتستخرج جزء اللغة إذا كان موجوداً.

import { defaultLocale, locales, type Locale } from "./locales";

export function getLocaleFromPathname(pathname: string): Locale {
  const segments = pathname.split("/").filter(Boolean);
  const firstSegment = segments[0];

  if (firstSegment && locales.includes(firstSegment as Locale)) {
    return firstSegment as Locale;
  }

  return defaultLocale;
}

تفحص هذه الدالة الجزء الأول من المسار وتُرجعه إذا كان يطابق لغة مدعومة، وإلا تعود إلى اللغة الافتراضية.

3. إنشاء دالة مساعدة لبناء المسارات المترجمة

اكتب دالة تأخذ المسار الحالي واللغة المستهدفة، ثم تنشئ مساراً جديداً مع استبدال جزء اللغة.

import { defaultLocale, locales, type Locale } from "./locales";

export function getLocalizedPath(
  pathname: string,
  targetLocale: Locale,
): string {
  const segments = pathname.split("/").filter(Boolean);
  const firstSegment = segments[0];

  const hasLocalePrefix =
    firstSegment && locales.includes(firstSegment as Locale);

  if (hasLocalePrefix) {
    segments[0] = targetLocale;
  } else {
    segments.unshift(targetLocale);
  }

  return "/" + segments.join("/");
}

تستبدل هذه الدالة جزء اللغة الموجود أو تضيف اللغة المستهدفة في بداية المسار، مما يضمن أن عنوان URL الجديد يشير إلى نفس الصفحة بلغة مختلفة.

4. بناء مكون تبديل اللغة

أنشئ مكوناً يستخدم الموقع الحالي لإنشاء روابط لجميع اللغات المدعومة.

import { Link } from "@tanstack/react-router";
import { useLocation } from "@tanstack/react-router";
import { locales, type Locale } from "./locales";
import { getLocaleFromPathname, getLocalizedPath } from "./locale-helpers";

export function LanguageSwitcher() {
  const location = useLocation();
  const currentLocale = getLocaleFromPathname(location.pathname);

  return (
    <nav>
      <ul>
        {locales.map((locale) => {
          const isActive = locale === currentLocale;
          const localizedPath = getLocalizedPath(location.pathname, locale);

          return (
            <li key={locale}>
              <Link
                to={localizedPath}
                search={location.search}
                hash={location.hash}
                aria-current={isActive ? "page" : undefined}
              >
                {locale.toUpperCase()}
              </Link>
            </li>
          );
        })}
      </ul>
    </nav>
  );
}

يقرأ المكون المسار الحالي، ويحدد اللغة النشطة، ويعرض رابطاً لكل لغة مدعومة يحافظ على بنية الصفحة الحالية ومعاملات البحث وجزء الهاش. يمكن للمستخدمين تبديل اللغات مع البقاء على نفس الصفحة المنطقية.