كيفية ربط إصدارات اللغات البديلة في React Router v7

ربط بدائل اللغات لمحركات البحث

المشكلة

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

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

الحل

أضف وسوم رابط hreflang إلى كل صفحة تسرد جميع إصدارات اللغات المتاحة لذلك المحتوى. تستخدم هذه الوسوم سمة rel="alternate" للإشارة إلى أن الصفحات المرتبطة هي ترجمات وليست نسخًا مكررة. تحدد كل وسم رمز لغة وتشير إلى عنوان URL لإصدار تلك اللغة.

من خلال الإعلان عن هذه العلاقات في البيانات الوصفية للصفحة، فإنك تساعد محركات البحث على فهم بنية موقعك وتقديم إصدار اللغة الصحيح لكل مستخدم. يؤدي هذا إلى تحسين ملاءمة نتائج البحث ويمنع عقوبات المحتوى المكرر.

الخطوات

1. إنشاء دالة مساعدة لبناء روابط hreflang

تستخدم سمة hreflang رموز اللغة ISO 639-1 متبوعة اختياريًا برموز المنطقة ISO 3166-1 Alpha 2. أنشئ أداة مساعدة تولد واصفات الروابط لجميع إصدارات اللغات للصفحة.

type HreflangLink = {
  tagName: "link";
  rel: "alternate";
  hrefLang: string;
  href: string;
};

export function buildHreflangLinks(
  pathname: string,
  locales: string[],
  baseUrl: string,
): HreflangLink[] {
  return locales.map((locale) => ({
    tagName: "link",
    rel: "alternate",
    hrefLang: locale,
    href: `${baseUrl}/${locale}${pathname}`,
  }));
}

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

2. إضافة رابط احتياطي x-default

تشير قيمة hreflang المسماة x-default إلى صفحة افتراضية عندما لا تكون هناك صفحة أخرى أكثر ملاءمة ولا تستهدف لغة أو لغة محلية معينة. أضف هذا لتوجيه المستخدمين الذين لا تدعم لغتهم.

export function buildHreflangLinks(
  pathname: string,
  locales: string[],
  baseUrl: string,
  defaultLocale: string,
): HreflangLink[] {
  const links = locales.map((locale) => ({
    tagName: "link",
    rel: "alternate",
    hrefLang: locale,
    href: `${baseUrl}/${locale}${pathname}`,
  }));

  links.push({
    tagName: "link",
    rel: "alternate",
    hrefLang: "x-default",
    href: `${baseUrl}/${defaultLocale}${pathname}`,
  });

  return links;
}

يشير رابط x-default عادةً إلى إصدار لغتك الأساسية ويعمل كبديل احتياطي للمستخدمين الذين لا تتطابق تفضيلات لغتهم مع أي من إصدارات اللغة المحددة لديك.

3. تصدير روابط hreflang من دالة meta

يمكن لدالة meta تعيين علامات الروابط بناءً على البيانات. استخدمها لإرجاع روابط hreflang لكل مسار.

import type { Route } from "./+types/about";
import { buildHreflangLinks } from "~/utils/hreflang";

const SUPPORTED_LOCALES = ["en", "fr", "de", "es"];
const BASE_URL = "https://example.com";
const DEFAULT_LOCALE = "en";

export function meta({ location }: Route.MetaArgs) {
  const hreflangLinks = buildHreflangLinks(
    location.pathname,
    SUPPORTED_LOCALES,
    BASE_URL,
    DEFAULT_LOCALE,
  );

  return [
    { title: "About Us" },
    { name: "description", content: "Learn about our company" },
    ...hreflangLinks,
  ];
}

تُرجع دالة meta مصفوفة من الواصفات التي يمكن أن تتضمن كائنات مع تعيين tagName إلى "link". يعرض React Router هذه العناصر كعناصر رابط في رأس المستند.

4. التأكد من وجود مكون Meta في التخطيط الجذري

يعرض مكون Meta جميع علامات meta التي تم إنشاؤها بواسطة تصدير meta لوحدة المسار ويجب أن يكون داخل رأس المستند. تحقق من أن التخطيط الجذري يتضمنه.

import { Links, Meta, Outlet, Scripts } from "react-router";

export default function Root() {
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <Meta />
        <Links />
      </head>
      <body>
        <Outlet />
        <Scripts />
      </body>
    </html>
  );
}

يجمع مكون Meta ويعرض جميع واصفات meta من المسار المطابق، بما في ذلك علامات رابط hreflang التي حددتها في الخطوة 3.

5. تكييف المسار للمسارات ذات البادئة اللغوية

إذا كانت مساراتك تتضمن اللغة المحلية في المسار (مثل /en/about)، فقم بإزالتها قبل بناء روابط hreflang بحيث تشير جميع إصدارات اللغة إلى نفس الصفحة المنطقية.

export function meta({ location }: Route.MetaArgs) {
  const pathWithoutLocale = location.pathname.replace(/^\/[a-z]{2}(\/|$)/, "/");

  const hreflangLinks = buildHreflangLinks(
    pathWithoutLocale,
    SUPPORTED_LOCALES,
    BASE_URL,
    DEFAULT_LOCALE,
  );

  return [{ title: "About Us" }, ...hreflangLinks];
}

يضمن هذا أن /en/about و/fr/about و/de/about جميعها تُنشئ روابط hreflang تشير إلى عناوين URL الصحيحة الخاصة باللغة لنفس المحتوى الأساسي.