为多语言创建站点地图索引

管理大型多语言网站以优化 SEO

问题

一个网站有大量的页面,覆盖多种语言。将每种语言的所有 URL 都列在一个巨大的 sitemap.xml 文件中效率低下,难以管理,并且可能超过文件大小限制。这使得更新某种语言的 URL 或让搜索引擎高效发现所有内容变得困难。

解决方案

创建一个作为“站点地图索引”的 sitemap.xml 文件,指向其他特定语言的站点地图(例如,sitemap-en.xmlsitemap-es.xml)。这种方法可以更好地组织内容,更易于管理,并且在添加新语言或页面时可以高效扩展。

步骤

1. 创建站点地图索引路由

替代 sitemap.ts 文件,您需要创建一个标准的路由处理器。这将使您能够完全控制生成站点地图索引。

创建 app/sitemap.xml/route.ts

// app/sitemap.xml/route.ts
import { locales, siteBaseUrl } from '@/i18n-config';

export async function GET() {
  const sitemapIndex = `<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  ${locales
    .map((locale) => {
      return `
    <sitemap>
      <loc>${siteBaseUrl}/sitemap-${locale}.xml</loc>
      <lastmod>${new Date().toISOString()}</lastmod>
    </sitemap>`;
    })
    .join('')}
</sitemapindex>
`;

  return new Response(sitemapIndex, {
    headers: {
      'Content-Type': 'application/xml',
    },
  });
}

此文件告诉搜索引擎您的站点地图是一个索引,指向其他文件,例如 sitemap-en.xmlsitemap-es.xml 等。

2. 为语言站点地图创建动态路由

接下来,创建动态路由以生成每种语言特定的站点地图。

创建 app/sitemap-[lang].xml/route.ts

// app/sitemap-[lang].xml/route.ts
import { locales, siteBaseUrl } from '@/i18n-config';

// 这告诉 Next.js 在构建时生成哪些站点地图
export async function generateStaticParams() {
  return locales.map((lang) => ({
    lang,
  }));
}

// 一个获取某种语言所有页面的辅助函数
// 在实际应用中,这将从 CMS 或数据库中获取数据
async function getPagesForLanguage(lang: string): Promise<string[]> {
  // 这些是相对路径,*不带*语言前缀
  // 例如,'/','/about','/blog/my-post'
  return ['/', '/about', '/contact'];
}

export async function GET(
  request: Request,
  { params }: { params: { lang: string } }
) {
  const { lang } = params;

  if (!locales.includes(lang)) {
    return new Response('Not Found', { status: 404 });
  }

  const pages = await getPagesForLanguage(lang);

  const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  ${pages
    .map((page) => {
      const path = page === '/' ? '' : page;
      return `
    <url>
      <loc>${siteBaseUrl}/${lang}${path}</loc>
      <lastmod>${new Date().toISOString()}</lastmod>
    </url>`;
    })
    .join('')}
</urlset>
`;

  return new Response(sitemap, {
    headers: {
      'Content-Type': 'application/xml',
    },
  });
}

现在,您的 sitemap.xml 文件是一个干净的索引,每种语言的 URL 都整齐地组织在各自的文件中(例如,/sitemap-en.xml),这些文件由此动态路由生成。