Next.js sitemap.xml 생성하기

JT·2025년 4월 24일
post-thumbnail

Sitemap(사이트맵)이란 웹사이트의 구조를 한눈에 보여주는 지도 같은 것입니다. 웹사이트 안에 어떤 페이지들이 있고, 그 페이지들이 어떻게 연결되어 있는지를 정리해 놓은 목록으로 검색 엔진(예: 구글, 네이버)을 위한 웹사이트의 지도입니다. 사이트의 페이지들을 자동으로 수집(크롤링)할 수 있게 도와주기 때문에 sitemap은 검색 엔진 최적화에 중요한 역할을 합니다.

Next.js v14 App Router 기준으로 sitemap.xml 생성 방법에 대해 설명합니다.

1. 정적 sitemap 생성하기

1 ) 직접 생성하기

간단한 사이트 같은 경우 app 폴더에서 sitemap.xml 파일을 만들어 정적 사이트맵을 생성할 수 있습니다.

예를 들어 main 페이지와 about 페이지가 존재한다고 하였을 때 아래와 같은 사이트 맵을 생성할 수 있습니다.

// /app/sitemap.xml
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://mysite.com</loc>
    <lastmod>2024-04-05T16:47:38.737Z</lastmod>
    <changefreq>daily</changefreq>
    <priority>1</priority>
  </url>
  <url>
    <loc>https://mysite.com/about</loc>
    <lastmod>2024-04-05T16:47:38.737Z</lastmod>
    <changefreq>daily</changefreq>
    <priority>0.8</priority>
  </url>
</urlset>

💡 sitemap 태그 설명

태그 이름필수 여부설명예시 값비고
<urlset>✅ 필수전체 sitemap을 감싸는 루트 요소. XML 네임스페이스 포함해야 함<urlset xmlns="...">하나의 sitemap에 한 번만 등장
<url>✅ 필수개별 URL 정보를 감싸는 요소<url> ... </url>여러 개 포함 가능
<loc>✅ 필수실제 페이지의 절대 경로(전체 URL)https://mysite.com/page1반드시 전체 URL 사용
<lastmod>⭕ 선택해당 페이지가 마지막으로 수정된 날짜2025-04-24T10:20:00+00:00ISO 8601 형식 권장
<changefreq>⭕ 선택페이지가 얼마나 자주 변경되는지를 나타냄always, daily, monthly검색 엔진 참고용
<priority>⭕ 선택해당 URL의 상대적 중요도 (0.0 ~ 1.0)0.8기본값은 0.5, SEO에 큰 영향 없음

2 ) next-sitemap 라이브러리 사용하기

생성할 정적 사이트맵의 수가 많은 경우 next-sitemap 라이브러리를 사용하여 빌드 시 자동으로 사이트맵이 생성되도록 할 수 있습니다.

next-sitemap 라이브러리를 사용하여 빌드 시 자동으로 사이트맵을 생성할 수 있습니다.

먼저, next-sitemap 라이브러리를 설치합니다.

npm i -D next-sitemap

package.json 파일 scripts에 명령어를 추가합니다.

//...
"scripts": {
  	//...
	"postbuild": "next-sitemap"
}
//...

root 폴더에 next-sitemap.config.js 파일을 생성합니다.

module.exports = {
  siteUrl: "https://mysite.com",
  generateRobotsTxt: true,
  sitemapSize: 5000,
  changefreq: "weekly",
  priority: 0.7,
  exclude: [], // 제외할 경로

이후 빌드 시 자동으로 public 폴더에 sitemap.xml 파일이 생성됩니다.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://mysite.com</loc>
    <lastmod>2025-04-24T09:32:12.000Z</lastmod>
  </url>
  <url>
    <loc>https://mysite.com/about</loc>
    <lastmod>2025-04-24T09:32:12.000Z</lastmod>
  </url>
</urlset>

💡 next-sitemap 동적 사이트 맵 생성

next-sitemap 라이브러리는 빌드 시 동적 사이트 맵을 생성하는 기능이 존재합니다.
이 기능은 next-sitemap.config.js 파일에 additionalPaths 옵션을 추가하여 설정할 수 있습니다.

아래는 포스트 동적 sitemap 생성을 추가하는 예시입니다.

const { getPostsId } = require('./lib/api');

module.exports = {
  siteUrl: "https://mysite.com",
  generateRobotsTxt: true,
  sitemapSize: 5000,
  changefreq: "weekly",
  priority: 0.7,
  exclude: [], // 제외할 경로
  additionalPaths: async () => {
   // 동적으로 sitemap 생성
   // 모든 포스터 아이디를 가져오는 API
  const postsId = await getPostsId();
   
  const postPaths = postsId.map((id) => ({
    loc: `/post/${id.toString()}`,
    lastmod: new Date().toISOString()
  }));
   
  return postPaths;
}

이후 빌드 시 자동으로 public 폴더에 sitemap.xml 파일이 생성됩니다.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://mysite.com</loc>
    <lastmod>2025-04-24T09:32:12.000Z</lastmod>
  </url>
  <url>
    <loc>https://mysite.com/about</loc>
    <lastmod>2025-04-24T09:32:12.000Z</lastmod>
  </url>
  <url>
    <loc>https://mysite.com/post/2</loc>
    <lastmod>2025-04-24T09:32:12.000Z</lastmod>
  </url>
   <url>
    <loc>https://mysite.com/post/1</loc>
    <lastmod>2025-04-24T09:32:12.000Z</lastmod>
  </url>
</urlset>

2. 동적 사이트 맵

Next.js에서는 app/sitemap.xml/route.ts를 이용하여 요청이 들어올 때마다 동적으로 sitemap을 생성할 수 있습니다.

app/sitemap.xml/route.ts 폴더 및 파일을 생성합니다.

// /app/sitemap.xml/route.ts
import { NextResponse } from 'next/server';
import { getPostsId } from '@/lib/api';

export default async function GET() {
  // 정적 URLs
  const staticURLs = [
     {
       loc:"https://mysite.com",
       lastmod:new Date().toISOString()
     },
          {
       loc:"https://mysite.com/about",
       lastmod:new Date().toISOString()
     }
   ];
  
  // 모든 포스트 아이디를 가져오는 API
  const postsId = await getPostsId();
  // 동적 postsURLs
  const postsURLs = postsId.map((p) => ({
    loc: `${BASE_URL}/product/${p._id.toString()}`,
    lastmod: new Date().toISOString()
  }));

  // 정적 urls, 동적 urls를 병합하여 sitemap 생성
  const urls = [...staticURLs, ...postsURLs]
   .map((data) => {
      return `
      <url>
        <loc>${data.loc}</loc>
        <lastmod>${data.lastmod}</lastmod>
      </url>
    `;
    })
    .join("");

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

  return new NextResponse(xml, {
    headers: {
      "Content-Type": "application/xml"
    }
  });
}

생성된 Sitemap.xml 파일

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://mysite.com</loc>
    <lastmod>2025-04-24T09:32:12.000Z</lastmod>
  </url>
  <url>
    <loc>https://mysite.com/about</loc>
    <lastmod>2025-04-24T09:32:12.000Z</lastmod>
  </url>
  <url>
    <loc>https://mysite.com/post/2</loc>
    <lastmod>2025-04-24T09:32:12.000Z</lastmod>
  </url>
   <url>
    <loc>https://mysite.com/post/1</loc>
    <lastmod>2025-04-24T09:32:12.000Z</lastmod>
  </url>
</urlset>
profile
함께 개선하는 프론트엔드 개발자

0개의 댓글