كيفية إنشاء خرائط مواقع متعددة اللغات في Next.js (Pages Router) الإصدار 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.