كيفية إنشاء خرائط مواقع متعددة اللغات في Next.js (موجه الصفحات) الإصدار 16

تنظيم خرائط المواقع حسب اللغة للتوسع

المشكلة

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

الحل

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

الخطوات

1. إنشاء صفحة فهرس خريطة الموقع

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

import { GetServerSideProps } from "next";

const SITE_URL = "https://example.com";
const LOCALES = ["en", "es", "fr", "de"];

function generateSitemapIndex(locales: string[]): string {
  const sitemapEntries = locales
    .map((locale) => {
      return `
<sitemap>
  <loc>${SITE_URL}/sitemap-${locale}.xml</loc>
  <lastmod>${new Date().toISOString()}</lastmod>
</sitemap>`;
    })
    .join("");

  return `<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${sitemapEntries}
</sitemapindex>`;
}

export const getServerSideProps: GetServerSideProps = async ({ res }) => {
  const sitemap = generateSitemapIndex(LOCALES);

  res.setHeader("Content-Type", "text/xml");
  res.write(sitemap);
  res.end();

  return {
    props: {},
  };
};

export default function SitemapIndex() {}

يستخدم الفهرس عنصر الجذر <sitemapindex> مع إدخالات <sitemap>، كل منها يحتوي على عنصر فرعي <loc> يشير إلى خريطة موقع خاصة بلغة معينة. تقوم وظيفة getServerSideProps بتعيين رأس Content-Type إلى text/xml وتكتب استجابة XML مباشرة.

2. إنشاء صفحات خريطة الموقع الخاصة باللغات

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

import { GetServerSideProps } from "next";

const SITE_URL = "https://example.com";

interface PageData {
  slug: string;
  lastModified: string;
}

async function getPagesByLocale(locale: string): Promise<PageData[]> {
  return [
    { slug: "about", lastModified: "2024-01-15" },
    { slug: "contact", lastModified: "2024-01-20" },
  ];
}

function generateSitemap(locale: string, pages: PageData[]): string {
  const urlEntries = pages
    .map((page) => {
      return `
<url>
  <loc>${SITE_URL}/${locale}/${page.slug}</loc>
  <lastmod>${page.lastModified}</lastmod>
</url>`;
    })
    .join("");

  return `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urlEntries}
</urlset>`;
}

export const getServerSideProps: GetServerSideProps = async ({
  params,
  res,
}) => {
  const locale = params?.locale as string;

  const pages = await getPagesByLocale(locale);
  const sitemap = generateSitemap(locale, pages);

  res.setHeader("Content-Type", "text/xml");
  res.write(sitemap);
  res.end();

  return {
    props: {},
  };
};

export default function LocaleSitemap() {}

يستخرج المسار الديناميكي اللغة من معلمات عنوان URL ويقوم بتوليد XML يحتوي فقط على عناوين URL لتلك اللغة. تظل كل خريطة موقع مركزة على محتوى لغة واحدة.

3. جلب المحتوى الخاص باللغة

استبدل دالة getPagesByLocale المؤقتة بمصدر البيانات الفعلي الخاص بك.

async function getPagesByLocale(locale: string): Promise<PageData[]> {
  const response = await fetch(
    `https://api.example.com/pages?locale=${locale}`,
  );
  const data = await response.json();

  return data.pages.map((page: any) => ({
    slug: page.slug,
    lastModified: page.updatedAt,
  }));
}

تقوم هذه الدالة بالاستعلام من نظام إدارة المحتوى الخاص بك أو قاعدة البيانات أو واجهة برمجة التطبيقات لاسترداد الصفحات للغة المحددة. وتقوم بإرجاع بيانات منظمة يقوم مولد خريطة الموقع بتحويلها إلى إدخالات XML.

4. إضافة صفحات ثابتة إلى كل خريطة موقع

قم بتضمين المسارات الثابتة الموجودة في كل لغة إلى جانب المحتوى الديناميكي.

function generateSitemap(locale: string, pages: PageData[]): string {
  const staticPages = [
    { slug: "", lastModified: new Date().toISOString() },
    { slug: "about", lastModified: new Date().toISOString() },
  ];

  const allPages = [...staticPages, ...pages];

  const urlEntries = allPages
    .map((page) => {
      const path = page.slug ? `/${locale}/${page.slug}` : `/${locale}`;
      return `
<url>
  <loc>${SITE_URL}${path}</loc>
  <lastmod>${page.lastModified}</lastmod>
</url>`;
    })
    .join("");

  return `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urlEntries}
</urlset>`;
}

يضمن الجمع بين الصفحات الثابتة والديناميكية اكتمال خريطة موقع كل لغة. تستخدم الصفحات الثابتة الطابع الزمني الحالي كتاريخ آخر تعديل لها.

5. الإشارة إلى الفهرس في ملف robots.txt

أضف موقع فهرس خريطة الموقع إلى ملف robots.txt الخاص بك حتى تكتشفه محركات البحث.

User-agent: *
Allow: /

Sitemap: https://example.com/sitemap.xml

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