Next.js에서 동적으로 sitemap.xml 만들기

date
Jul 1, 2022
slug
hot-to-make-sitemap-in-next-js
status
Published
tags
SEO
Blog
Next.js
summary
sitemap을 동적으로 불러오도록 해보자
type
Post
Updated At
Aug 1, 2022 01:18 AM
Created At
Jun 28, 2022 02:45 PM

시작하며

내 블로그를
craigary/nobelium
을 기반으로 만들고 있었는데, 확인해보니 sitemap을 배포하는 경우에 작성된 게시글을 긁어와서 생성하는 구조로 되어있었다.
해당 형태라면 배포한 이후에 작성한 게시글에 대해서는 sitemap이 생성되지 않기 때문에 seo관점에서 불리한 측면이 있어 동적으로 sitemap을 생성할 수 있도록 바꾸어 보려고 한다.

Pages 디렉터리에 sitemap.xml 컴포넌트 생성

일반적으로 sitemap.xml을 [url]/sitemap.xml 으로 robots.txt에 명시해두기 때문에 해당 컴포넌트를 생성해주자.
이곳에서 next.js에서 제공하는 getServerSideProps 을 사용하면 server side에서 sitemap을 생성해서 response 할 수 있다.

// pages/sitemap.xml.js

const Sitemap = () => {
  return null
}

export const getServerSideProps = async ({ res }) => {
  // 이곳에서 sitemap을 생성해주면 된다.
}

export default Sitemap

sitemap 동적으로 생성해서 response하기

실제 내 블로그에서 사용하는 코드는 아래와 같다.
export const getServerSideProps = async ({ res }) => {
  // post url 가져오기
  const posts = await getAllPosts({ includePages: true })
  const dynamicPaths = posts.map(post => {
    return `${link}/${post.slug}`
  })

  const allPaths = [...dynamicPaths]

  const sitemap = `
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/0.7" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
      <url>
        <loc>${link}</loc>
        <changefreq>daily</changefreq>
        <priority>0.7</priority>
        <lastmod>${new Date().toISOString()}</lastmod>
      </url>
      <url>
        <loc>${link}/feed</loc>
        <changefreq>daily</changefreq>
        <priority>0.7</priority>
        <lastmod>${new Date().toISOString()}</lastmod>
      </url>
    ${allPaths
      .map((url) => {
        return `
          <url>
            <loc>${url}</loc>
            <changefreq>daily</changefreq>
            <priority>0.7</priority>
            <lastmod>${new Date().toISOString()}</lastmod>
          </url>
        `
      })
      .join("")}
    </urlset>
  `

  res.setHeader('Content-Type', 'text/xml')
  res.write(sitemap)
  res.end()

  return {
    props: {},
  }
}
동적으로 가져오고자하는 데이터를 가져와 sitemap을 생성하였다. 각자 본인에게 맞는 데이터를 가져와 임의적으로 넣어주면 된다.
정적인 페이지의 경우 몇가지 없기 때문에 그냥 작성해두었다.

마치며

google search console에 등록해도 계속 인식이 안되고 바로바로 반영되는게 아니여서 거슬렸는데, 며칠 기다리니까 정상적으로 인식되었다 👍