كيفية ربط إصدارات اللغات البديلة في Next.js (Pages Router) v16
ربط بدائل اللغات لمحركات البحث
المشكلة
عندما يقدم موقع ويب نفس المحتوى بلغات متعددة، تواجه محركات البحث عناوين URL منفصلة لكل إصدار دون فهم العلاقة بينها. قد يرى مستخدم فرنسي يبحث الإصدار الإنجليزي مرتبًا أعلى من الإصدار الفرنسي، حتى لو كان كلاهما موجودًا. وبالمثل، قد تُعامل الصفحة الإنجليزية وترجمتها الفرنسية كنسخ مكررة متنافسة بدلاً من بدائل منسقة. بدون إشارات صريحة تربط إصدارات اللغات هذه، لا تستطيع محركات البحث تقديم الإصدار الأنسب للمستخدمين بثقة بناءً على تفضيلات اللغة الخاصة بهم، مما يؤدي إلى تجزئة سلطة الترتيب وتجربة مستخدم سيئة.
الحل
أضف عناصر link مع سمات hreflang إلى قسم head في كل صفحة، مع سرد جميع إصدارات اللغات بما في ذلك الصفحة نفسها. يجب أن يتضمن كل متغير صفحة مجموعة متطابقة من الروابط تشير إلى كل إصدار لغة متاح. يضمن هذا الربط ثنائي الاتجاه أن تتعرف محركات البحث على الصفحات كترجمات بدلاً من نسخ مكررة، مما يسمح لها بتقديم إصدار اللغة الصحيح للمستخدمين بناءً على تفضيلات المتصفح وسياق البحث.
الخطوات
1. إنشاء مكون لتوليد روابط اللغات البديلة
استورد مكون Head من next/head لتعديل البيانات الوصفية للصفحة. الوصول إلى معلومات اللغة عبر خطاف useRouter لبناء روابط لجميع إصدارات اللغات المتاحة.
import Head from "next/head";
import { useRouter } from "next/router";
interface AlternateLinksProps {
path?: string;
}
export default function AlternateLinks({ path }: AlternateLinksProps) {
const router = useRouter();
const { locales, locale: currentLocale, asPath } = router;
const canonicalPath = path || asPath;
if (!locales) {
return null;
}
return (
<Head>
{locales.map((locale) => (
<link
key={locale}
rel="alternate"
hrefLang={locale}
href={`${process.env.NEXT_PUBLIC_SITE_URL}/${locale}${canonicalPath}`}
/>
))}
</Head>
);
}
يقوم المكون بالتكرار عبر اللغات المتاحة من الموجه وينشئ عناصر link ديناميكيًا لجميع الصفحات.
2. إضافة المكون إلى الصفحات التي لها ترجمات
قم بتضمين مكون AlternateLinks في كل مكون صفحة موجود بلغات متعددة.
import AlternateLinks from "@/components/AlternateLinks";
export default function AboutPage() {
return (
<>
<AlternateLinks />
<main>
<h1>About Us</h1>
</main>
</>
);
}
يضمن المكون أن كل صفحة تتضمن المجموعة الكاملة من الروابط البديلة، مما يلبي متطلب أن تشير جميع المتغيرات إلى بعضها البعض.
3. تضمين رابط ذاتي للغة المحلية الحالية
يجب أن تتضمن كل صفحة وسم hreflang ذاتي يشير إلى لغتها الخاصة. يتعامل المكون مع هذا بالفعل من خلال التكرار عبر جميع اللغات المحلية بما في ذلك اللغة الحالية.
export default function AlternateLinks({ path }: AlternateLinksProps) {
const router = useRouter();
const { locales, asPath } = router;
const canonicalPath = path || asPath;
if (!locales) {
return null;
}
return (
<Head>
{locales.map((locale) => (
<link
key={locale}
rel="alternate"
hrefLang={locale}
href={`${process.env.NEXT_PUBLIC_SITE_URL}/${locale}${canonicalPath}`}
/>
))}
</Head>
);
}
تتضمن كل صفحة الآن وسوم hreflang تشير إلى نفسها إلى جانب الوسوم الخاصة بالإصدارات الأخرى.
4. إضافة رابط احتياطي x-default
أضف رابط x-default لتحديد الإصدار الذي يجب أن يراه المستخدمون عندما لا تكون لغتهم متاحة.
export default function AlternateLinks({ path }: AlternateLinksProps) {
const router = useRouter();
const { locales, defaultLocale, asPath } = router;
const canonicalPath = path || asPath;
if (!locales || !defaultLocale) {
return null;
}
return (
<Head>
{locales.map((locale) => (
<link
key={locale}
rel="alternate"
hrefLang={locale}
href={`${process.env.NEXT_PUBLIC_SITE_URL}/${locale}${canonicalPath}`}
/>
))}
<link
rel="alternate"
hrefLang="x-default"
href={`${process.env.NEXT_PUBLIC_SITE_URL}/${defaultLocale}${canonicalPath}`}
/>
</Head>
);
}
يوجه رابط x-default المستخدمين الذين لا تتطابق تفضيلات لغتهم إلى اللغة المحلية الافتراضية.