为多语言网站创建 sitemap 索引
管理大型多语言站点以提升 SEO
问题
一个网站拥有大量页面,并支持多种语言。如果将所有语言的每个 URL 都列在一个庞大的 sitemap.xml 文件中,不仅效率低下,难以维护,还可能超出文件大小限制。这会导致单独更新某一语言的 URL 变得困难,也不利于搜索引擎高效发现全部内容。
解决方案
创建一个 sitemap.xml 文件,作为“sitemap 索引”,指向其他按语言划分的 sitemap(例如 sitemap-en.xml、sitemap-es.xml)。这种方式可以更好地组织内容,便于管理,并且在新增语言或页面时具备良好的扩展性。
步骤
1. 创建 sitemap 索引路由
与直接使用 sitemap.ts 文件不同,你需要创建一个标准的路由处理器。这样可以完全自定义 sitemap 索引的生成方式。
创建 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](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 是一个索引文件,指向其他文件,如 sitemap-en.xml、sitemap-es.xml 等。
2. 创建语言 sitemap 的动态路由
接下来,创建动态路由,用于生成每种语言对应的 sitemap。
创建 app/sitemap-[lang].xml/route.ts。
// app/sitemap-[lang].xml/route.ts
import { locales, siteBaseUrl } from '@/i18n-config';
// This tells Next.js which sitemaps to build at build time
export async function generateStaticParams() {
return locales.map((lang) => ({
lang,
}));
}
// A helper function to get all pages for a language
// In a real app, this would fetch from a CMS or database
async function getPagesForLanguage(lang: string): Promise<string[]> {
// These are relative paths, *without* the lang prefix
// e.g., '/', '/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](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),这些文件由该动态路由生成。