كيفية ربط إصدارات اللغات البديلة في TanStack Start v1
ربط بدائل اللغة لمحركات البحث
المشكلة
عندما يقدم موقع إلكتروني نفس المحتوى بلغات متعددة، تتعامل محركات البحث مع كل نسخة لغوية كصفحة منفصلة بشكل افتراضي. بدون إشارات صريحة تربط بين هذه النسخات، لا تستطيع محركات البحث فهم أن /en/about و /fr/about هما ترجمتان لنفس المحتوى وليسا نسختين متكررتين متنافستين. هذا التجزئة تقسم سلطة الترتيب عبر النسخات اللغوية وتخلق مشاكل في التقديم: قد يرى مستخدم ناطق بالفرنسية النسخة الإنجليزية مرتبة أعلى في نتائج البحث، حتى مع وجود ترجمة فرنسية. تحتاج محركات البحث إلى بيانات وصفية صريحة لفهم العلاقة بين المتغيرات اللغوية وتقديم النسخة المناسبة بناءً على تفضيلات لغة المستخدم وموقعه.
الحل
أضف عناصر ارتباط hreflang إلى رأس المستند التي تعلن عن جميع النسخات اللغوية المتاحة لكل صفحة. تخبر هذه الروابط محركات البحث أي عناوين URL تحتوي على نفس المحتوى بلغات مختلفة، مما يسمح لها بتوحيد إشارات الترتيب وتقديم النسخة الصحيحة للمستخدمين. تسرد كل صفحة جميع بدائلها اللغوية، بما في ذلك إشارة إلى نفسها، مما يخلق علاقة ثنائية الاتجاه تستخدمها محركات البحث لفهم هيكل الترجمة. تتم إضافة هذه البيانات الوصفية لكل مسار باستخدام نظام إدارة الرأس الخاص بالإطار، والذي يمكنه الوصول إلى معلمات المسار الحالية اللازمة لإنشاء عناوين URL لجميع المتغيرات اللغوية.
الخطوات
1. إنشاء مساعد لبناء عناوين URL البديلة للغات
تقوم طريقة buildLocation الخاصة بالموجه ببناء عناوين URL كاملة من معلمات المسار، والتي ستستخدمها لإنشاء عناوين URL لكل نسخة لغوية.
import { AnyRouter } from "@tanstack/react-router";
export function buildLanguageAlternates(
router: AnyRouter,
currentPath: string,
currentLang: string,
availableLanguages: string[],
) {
return availableLanguages.map((lang) => {
const location = router.buildLocation({
to: currentPath,
params: { lang },
});
return {
lang,
href: `${location.pathname}${location.search}${location.hash}`,
};
});
}
تأخذ هذه الدالة مسار المسار الحالي وتنشئ عناوين URL بديلة عن طريق استبدال كل رمز لغة في معلمات المسار.
2. حدد اللغات المتاحة لديك
قم بإنشاء ملف تكوين يسرد جميع اللغات التي يدعمها تطبيقك.
export const AVAILABLE_LANGUAGES = ["en", "fr", "de", "es"];
export const DEFAULT_LANGUAGE = "en";
ستُستخدم هذه القائمة المركزية لإنشاء روابط hreflang لكل صفحة.
3. أضف روابط hreflang في دالة head للمسار
تستقبل دالة head سياقًا يتضمن matches وparams وloaderData، مما يوفر وصولاً إلى معلمة اللغة الحالية ومثيل الموجه.
import { createFileRoute } from "@tanstack/react-router";
import { buildLanguageAlternates, AVAILABLE_LANGUAGES } from "../i18n-config";
export const Route = createFileRoute("/$lang/about")({
head: ({ params }) => {
const alternates = buildLanguageAlternates(
Route.router,
"/$lang/about",
params.lang,
AVAILABLE_LANGUAGES,
);
return {
links: alternates.map((alt) => ({
rel: "alternate",
hreflang: alt.lang,
href: alt.href,
})),
};
},
component: AboutPage,
});
function AboutPage() {
return <div>About page content</div>;
}
تستخدم سمة hreflang رموز اللغة ISO 639-1، وكل رابط يشير إلى نفس الصفحة بلغة مختلفة.
4. أضف hreflang من نوع x-default لسلوك الرجوع الاحتياطي
تشير سمة hreflang من نوع x-default إلى الصفحة الافتراضية عندما لا تتطابق أي لغة.
export const Route = createFileRoute("/$lang/about")({
head: ({ params }) => {
const alternates = buildLanguageAlternates(
Route.router,
"/$lang/about",
params.lang,
AVAILABLE_LANGUAGES,
);
const defaultUrl = alternates.find((alt) => alt.lang === "en");
return {
links: [
...alternates.map((alt) => ({
rel: "alternate",
hreflang: alt.lang,
href: alt.href,
})),
{
rel: "alternate",
hreflang: "x-default",
href: defaultUrl?.href || alternates[0].href,
},
],
};
},
component: AboutPage,
});
يوفر رابط x-default عنوان URL احتياطي للمستخدمين الذين لا تتطابق تفضيلات لغتهم مع أي بديل معلن.
5. التطبيق على المسارات الديناميكية ذات المعلمات
بالنسبة للمسارات التي تحتوي على أجزاء ديناميكية إضافية بخلاف اللغة، قم بتضمين تلك المعلمات عند بناء البدائل.
export const Route = createFileRoute("/$lang/posts/$postId")({
head: ({ params }) => {
const alternates = AVAILABLE_LANGUAGES.map((lang) => {
const location = Route.router.buildLocation({
to: "/$lang/posts/$postId",
params: { lang, postId: params.postId },
});
return {
lang,
href: `${location.pathname}${location.search}${location.hash}`,
};
});
return {
links: [
...alternates.map((alt) => ({
rel: "alternate",
hreflang: alt.lang,
href: alt.href,
})),
{
rel: "alternate",
hreflang: "x-default",
href:
alternates.find((a) => a.lang === "en")?.href || alternates[0].href,
},
],
};
},
});
يجب أن تشير كل صفحة إلى جميع إصدارات اللغة الخاصة بها، بما في ذلك نفسها، لضمان فهم محركات البحث للمجموعة الكاملة من الترجمات لهذا المحتوى.
6. التحقق من تنفيذ hreflang
تقوم دالة head بإرجاع عناصر الرابط التي يتم عرضها بواسطة مكون HeadContent. قم بفحص HTML المعروض للتأكد من ظهور الروابط في رأس المستند.
<link rel="alternate" hreflang="en" href="/en/about" />
<link rel="alternate" hreflang="fr" href="/fr/about" />
<link rel="alternate" hreflang="de" href="/de/about" />
<link rel="alternate" hreflang="es" href="/es/about" />
<link rel="alternate" hreflang="x-default" href="/en/about" />
تضمن الروابط ثنائية الاتجاه بين الصفحات فهم محركات البحث للعلاقة بين الإصدارات المترجمة، مما يتيح لها تقديم الإصدار الأكثر ملاءمة لكل مستخدم.