Next.js 크롤링 및 색인 생성

프로젝트
프로젝트
카테고리
Dev
작성일
2023-10-05
태그
TIL
작성자
꾸생
상태
공개

Sitemap.xml

사이트맵은 검색 엔진이 웹사이트 컨텐츠를 효율적으로 크롤링할 수 있도록 알려주는 지도와 같다. 사이트의 페이지, 동영상, 기타 파일 등 이들 간의 관계 정보도 담고 있다. 웹사이트에 사이트맵을 잘 준비해 놓는다면 검색 엔진이 좋아할 거다.
사이트맵을 직접 작성한다면 XML 형식의 스키마를 이해하고 있어야 하는데, 아래 간단한 규칙과 태그 정의만 이해하고 간단하게 작성하도록 하자.. 깊게 들어가면 어렵다 🥹

Sitemap 규칙

  • 여는 <urlset> 태그로 시작해 닫는 </urlset> 태그로 끝납니다
  • <urlset> 태그 안에 네임스페이스(프로토콜 표준)를 지정합니다.
  • 각 URL의 <url> 항목을 상위 XML 태그로 포함시켜야 합니다.
  • 각 <url> 상위 태그에 <loc> 하위 항목을 포함시켜야 합니다.

XML 태그 정의

속성
설명
<urlset>
필수
파일을 캡슐화하고 현재 프로토콜 표준을 참조합니다.
<url>
필수
각 URL 항목의 상위 태그. 나머지 태그는 이 태그의 하위 태그입니다.
<loc>
필수
페이지의 URL. 해당 URL은 http 같은 프로토콜로 시작해야 하며 웹서버에 따라 슬래시로 끝나야 합니다. 이 값은 2,048자 미만이어야 합니다.
<lastmod>
옵션
파일을 마지막으로 수정한 날짜입니다. 이 날짜는 W3C Datetime 형식이어야 합니다. 이 형식에서는 시간 부분을 생략할 수 있으며 원하는 경우 YYYY-MM-DD 형식을 사용할 수 있습니다. 이 태그는 서버에서 반환할 수 있는 If-Modified-Since(304) 헤더와 다르므로 검색 엔진은 두 소스에서 다른 정보를 사용할 수 있습니다.
<changefreq>
옵션
페이지가 변경되는 빈도. 이 값은 검색 엔진에 일반적인 정보를 제공하며 검색 엔진에서 페이지를 크롤링하는 정확한 빈도와는 관련이 없을 수도 있습니다. 유효한 값은 다음과 같습니다.alwayshourlydailyweeklymonthlyyearlynever 값 "always"는 액세스할 때마다 변경되는 문서를 설명하는 데 사용해야 합니다. 값 "never"는 보관된 URL을 설명하는 데 사용해야 합니다. 태그의 값은 힌트 이지 명령이 아닙니다.검색 엔진 크롤러에서 결정을 내릴 때 해당 정보를 고려하더라도 "hourly"이라고 표시된 페이지를 이보다 더 적은 빈도로 크롤링하고 "yearly"이라고 표시된 페이지를 이보다 더 자주 크롤링할 수 있습니다.크롤러는 "절대 하지 않음(never)"이라고 표시된 페이지가 예기치 않게 변경되더라도 이를 처리할 수도 있도록해당 페이지도 정기적으로 크롤링합니다.
<priority>
옵션
해당 사이트의 기타 URL에 대한 특정 URL의 상대적 우선순위.유효값 범위는 0.0-1.0입니다.이 값은 다른 사이트의 페이지와 귀하의 페이지를 비교하는 방식에 아무런 영향을 주지 않으며, 귀하가 귀하의 사이트에서 크롤러에 가장 중요하다고 생각하는 페이지를 검색 엔진에 알리기만 합니다. 페이지의 기본 우선순위는 0.5입니다. 귀하가 페이지에 지정한 우선순위는 검색 엔진의 결과 페이지에서 URL의 순위에 별 영향을 미치지 않습니다.검색 엔진에서는 같은 사이트에 있는 URL 중 하나를 선택할 때 이러한 정보를 사용할 수 있으므로 해당 태그를 사용하면 같은 사이트 내에서 중요도가 높은 페이지가 검색색인에 나타나게 할 가능성을 높일 수는 있습니다. 또한 사이트의 모든 URL에 높은 우선순위를 지정해도 사이트의 순위를 높이는 데는 아무런 도움이 되지 않습니다.우선순위는 상대적인 것으로 사이트 내의 URL 중 하나를 선택하는 데만 사용됩니다.

Next.js 사이트맵 생성

Next.js 프레임워크에서 사이트맵을 추가하는 방법은 3가지가 있다. 수동, 동적 생성, 라이브러리를 사용하는 방법인데, 상황에 맞게 잘 사용해보자.

수동 생성

<!-- public/sitemap.xml --> <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-10-05</lastmod> </url> <url> <loc>http://www.example.com/about</loc> <lastmod>2023-10-05</lastmod> </url> <url> <loc>http://www.example.com/notice</loc> <lastmod>2023-10-05</lastmod> </url> </urlset> </xml>
단순한 페이지로 구성된 웹사이트의 경우 프로젝트 루트 경로에 존재하는 public 디렉토리 안에 아래 파일을 만들어주고 내용을 작성하면 된다. 파일 명은 sitemap.xml 로 네이밍 해준다. <url/> 태그 안에 lastMod 또는 priority와 같이 작성하고 싶은 태그를 넣어 입력해주면 된다.

동적 생성

Next.js의 SSR을 사용해 사이트맵 요청 시 XML 형식의 문서를 만들어 반환해주는 방법이다. page 라우터를 사용한다면 pages 디렉토리 안에 sitemap.xml.js 또는 sitemap.xml.ts 파일을 작성해준다.
//pages/sitemap.xml.js const EXTERNAL_DATA_URL = 'https://jsonplaceholder.typicode.com/posts'; function generateSiteMap(posts) { return `<?xml version="1.0" encoding="UTF-8"?> <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> <!--We manually set the two URLs we know already--> <url> <loc>https://jsonplaceholder.typicode.com</loc> </url> <url> <loc>https://jsonplaceholder.typicode.com/guide</loc> </url> ${posts .map(({ id }) => { return ` <url> <loc>${`${EXTERNAL_DATA_URL}/${id}`}</loc> </url> `; }) .join('')} </urlset> `; } function SiteMap() { // getServerSideProps will do the heavy lifting } export async function getServerSideProps({ res }) { // We make an API call to gather the URLs for our site const request = await fetch(EXTERNAL_DATA_URL); const posts = await request.json(); // We generate the XML sitemap with the posts data const sitemap = generateSiteMap(posts); res.setHeader('Content-Type', 'text/xml'); // we send the XML to the browser res.write(sitemap); res.end(); return { props: {}, }; } export default SiteMap;
위 예제는 글 목록을 가져와 xml 형식으로 사이트맵을 만들어주는 함수를 사용한다. 웹사이트에 맞는 방법으로 함수를 만들어주면 된다.

3. 라이브러리 사용

기존에 라이브러리를 사용했는데, 이번에 마이그레이션을 진행하면서 수동으로 작성하는 방법을 적용했다.

🤖 robot.txt

사이트맵을 만들었다면 robot.txt 파일도 추가해주는 걸 잊어선 안된다. 검색 엔진한테 사이트맵 경로와 어디까지 크롤링해도 되는지 등 미리 알려줄 수 있다.
User-Agent: * Allow: / Disallow: /api/ Sitemap: https://www.example.com/sitemap.xml
public/robot.txt 경로에 작성해준다.

출처