Post

[Next.js] Next.js에서 XML Sitemap 만들기

XML Sitemap이란?

사이트맵은 사이트의 페이지, 동영상 및 기타 파일들에 대한 정보를 제공하는 파일입니다. 누구한테 제공하냐면 사이트를 읽고 검색 엔진에 보여주는 크롤러에게 제공합니다. 사이트맵을 만드는 이유는 크롤러가 내 사이트를 크롤링하기 전에 어떤 페이지와 어떤 컨텐츠가 있는지 요약 정보를 제공해 줌으로써 좀 더 효율적인 크롤링을 가능하게 해 주기 때문입니다.

구글 공식 문서에 따르면, 사이트맵이 필요한 경우는 다음과 같습니다.

  • 사이트의 규모가 큰 경우
  • 만든지 얼마 안 됐거나 외부 링크가 적은 경우
  • 페이지 간 연결이 잘 안 되어있거나 개별적으로 존재하는 페이지가 많은 경우
  • 비디오나 이미지처럼 미디어 컨텐츠가 많거나 구글 뉴스에 나온 경우

사이트맵이 잘 작성되어 있는 경우 크롤링이나 검색 순위에도 영향이 있다고 하니 검색 노출이 중요한 웹사이트라면 만들어 놓는 게 여러모로 좋다고 생각합니다.

 

XML Sitemap에서 사용하는 태그들

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
   <url>
      <loc>http://www.example.com/</loc>
      <lastmod>2023-01-01</lastmod>
      <changefreq>monthly</changefreq>
      <priority>0.8</priority>
   </url>
</urlset>

<urlset>

  • 필수 입력 사항
  • <url>을 감싸는 부모 요소입니다.

<url>

  • 필수 입력 사항
  • url 관련 정보들을 감싸는 부모 요소입니다.

<log>

  • 필수 입력 사항
  • url 주소를 적는 요소입니다.

<lastmod>

  • 선택 입력 사항
  • 마지막으로 수정된 날짜를 적는 요소입니다.
  • w3 표준시로 작성되어야 합니다.

<changefreq>

  • 선택 입력 사항
  • 얼마나 자주 컨텐츠가 변경되는지 적는 요소입니다.
  • 유효한 값으로 always, hourly, daily, weekly, monthly, yearly, never가 있습니다.
  • 방문할 때마다 바뀌는 부분이 있으면 “always”에 해당되고, 앞으로 바뀔 일이 절대 없으면 “never”에 해당됩니다.
  • 어느 주기로 크롤링을 해야 될지 기준을 제공해 주지만, 그렇다고 무조건 이 기준대로 크롤링이 되는 건 아닙니다.

<priority>

  • 선택 입력 사항
  • 내 사이트에서 어떤 걸 우선 순위로 두어야 될지를 정하는 요소입니다.
  • 기본값은 0.5, 최소 값은 0.0, 최댓값은 1.0입니다.
  • <changefreq>와 마찬가지로 우선순위를 크롤러에 제공할 뿐, 무조건 우선 순위대로 크롤링이 되는 건 아닙니다.
  • 내 사이트 내에서의 상대적인 우선 순위를 정하는 거기 때문에 전부 1로 넣는다고 해서 좋을 건 없습니다.

 

Next.js에서 사이트맵 만들기

Next.js에서 사이트맵을 만드는 방법은 두 가지가 있습니다.

정적 사이트맵

내 사이트에 페이지가 많지 않거나, 페이지 수가 제한되어 있는 경우 정적 사이트맵을 만들어서 /public 폴더 안에 넣어주기만 하면 됩니다. 정적 사이트맵은 직접 제작할 수도 있지만, 자동으로 제작해 주는 사이트도 많이 있어서 이런 사이트들을 이용하면 손쉽게 제작할 수 있습니다.

https://www.xml-sitemaps.com/

위 도메인에 접속해 네모 박스에 url만 입력하면 자동으로 사이트맵을 만들어 줍니다.

https://www.xml-sitemaps.com https://www.xml-sitemaps.com

동적 사이트맵

동적 사이트맵은 다른 페이지들과 동일하게 getServerSideProps로 만들 수 있습니다. 먼저 /pages 폴더 안에 sitemap.xml.js, 타입스크립트를 사용 중이라면 sitemap.xml.tsx 파일을 만들어 줍니다. 그 후 getServerSideProps 안에 API를 호출해 원하는 데이터를 불러와 동적으로 넣어주면 됩니다.

sitemap.xml.tsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
function generateSiteMap(posts: any) {
	return `<?xml version="1.0" encoding="UTF-8"?>
        <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
        <!-- 정적인 페이지는 수동으로 입력 -->
        <url>
            <loc>https://taedonn.tistory.com</loc>
            <lastmod>2023-12-05T15:39:57+09:00</lastmod>
            <priority>1.0</priority>
        </url>
        .
        .
        .
        <!-- 동적인 페이지는 map() 함수를 통해 distribute -->
        ${
            posts.map((post: any) => {
                return `
                    <url>
                        <loc>https://taedonn.tistory.com/${post.id}</loc>
                    </url>
                `;
            }).join('')
        }
        </urlset>`;
}

function SiteMap() {
	// 비워두고 getServerSideProps에서 res.write()를 통해 브라우저에 XML을 보낸다.
}

export async function getServerSideProps({ res }: { res: any }) {
	// API를 호출해 데이터를 받아온다.
    const request = await fetch("API 주소");
    const posts = await request.json();
    
    // 사이트맵 구조를 받아온다.
    const sitemap = generateSiteMap(posts);
    
    // sitemap 변수에 저장한 XML 사이트맵을 SiteMap 컴포넌트에 내보낸다.
    res.setHeader("Content-Type", "text/xml");
    res.write(sitemap);
    res.end();
    
    return {
    	props: {},
    }
}

export default function SiteMap;

이렇게 해서 완성된 사이트맵. 아래 동적인 부분은 데이터가 추가될 때마다 반영되어 보입니다.

https://taedonn.tistory.com/sitemap.xml https://taedonn.tistory.com/sitemap.xml

 

참고

This post is licensed under CC BY 4.0 by the author.