다국어를 위한 사이트맵 인덱스 생성하기
SEO를 위한 대규모 다국어 사이트 관리
문제
사이트에 여러 언어로 된 많은 페이지가 있습니다. 모든 언어의 모든 URL을 나열하는 단일 대용량 sitemap.xml 파일은 비효율적이고 관리하기 어려우며 파일 크기 제한을 초과할 수 있습니다. 이로 인해 한 언어의 URL을 업데이트하거나 검색 엔진이 모든 콘텐츠를 효율적으로 발견하기 어렵습니다.
해결책
"사이트맵 인덱스" 역할을 하는 sitemap.xml 파일을 만들어 다른 언어별 사이트맵(예: sitemap-en.xml, sitemap-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](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.xml, sitemap-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](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)에 깔끔하게 구성됩니다.