Language/Next.js

[Next.js] Sitemap 설정 방법 (13버전 App Router)

  • -
반응형

13버전 이전에서는 `next-seo`라는 라이브러리를 사용하여 보통 메타데이터를 설정하였는데, 13버전 이상부터는 메타데이터 관련하여 `Metadata` API를 따로 지원한다. 그리고 sitemap 관련하여 app 폴더에서 바로 sitemap.js 파일을 만들어 `MetadataRoute`라는 API도 역시 지원한다. 이번 글에서는 13버전 이상, App Router에서 Sitemap.xml 설정하는 방법을 알아보자

[Next.js] Sitemap
[Next.js] Sitemap

Sitemap이란?

Sitemap은 웹사이트의 구조를 검색 엔진에게 알려주는 XML 형식의 파일이나 페이지의 목록을 의미합니다. 이는 검색 엔진이 웹사이트를 효율적으로 크롤링하고 색인화하는 데 도움이 됩니다. Sitemap은 일반적으로 웹사이트의 모든 페이지 URL과 해당 페이지의 중요한 정보를 포함하고 있습니다.

Sitemap의 주요 목적은 다음과 같습니다:

  1. 검색 엔진 크롤러 지원: 검색 엔진은 웹사이트를 크롤링하여 그 내용을 색인화합니다. Sitemap을 제공하면 크롤러가 웹사이트의 중요한 페이지를 신속하게 발견하고 색인화할 수 있습니다.
  2. 웹사이트 구조 표시: Sitemap은 웹사이트의 구조를 나타내므로 검색 엔진은 웹사이트의 계층 구조를 이해하고 사용자에게 더 나은 검색 결과를 제공할 수 있습니다.
  3. 중요한 정보 제공: 각 페이지의 최종 수정 날짜, 변경 빈도, 우선순위 등과 같은 추가 정보를 Sitemap에 포함시켜 검색 엔진에게 페이지의 중요성을 알려줄 수 있습니다.

일반적으로 Sitemap은 웹사이트의 루트 디렉토리에 위치하며, 검색 엔진은 robots.txt 파일을 통해 해당 Sitemap 파일의 위치를 확인합니다. 웹사이트가 크거나 동적인 콘텐츠를 가지고 있는 경우 특히 유용하며, 검색 엔진이 모든 페이지를 효과적으로 색인화하도록 도와줍니다. Next.js에는 sitemap.(xml|js|ts)Sitemaps XML 형식 과 일치하는 특수 파일입니다.검색 엔진 크롤러가 사이트를 보다 효율적으로 색인화하는 데 도움이 됩니다.

설정 방법

1. .xml 파일을 직접 올리는 방법

sitemap.xml소규모 애플리케이션의 경우 파일을 생성하여 디렉터리 루트에 배치 할 수 있습니다 app.

// app/sitemap.xml
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://acme.com</loc>
    <lastmod>2023-04-06T15:02:24.021Z</lastmod>
    <changefreq>yearly</changefreq>
    <priority>1</priority>
  </url>
  <url>
    <loc>https://acme.com/about</loc>
    <lastmod>2023-04-06T15:02:24.021Z</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.8</priority>
  </url>
  <url>
    <loc>https://acme.com/blog</loc>
    <lastmod>2023-04-06T15:02:24.021Z</lastmod>
    <changefreq>weekly</changefreq>
    <priority>0.5</priority>
  </url>
</urlset>

2. 코드(.js, .ts)를 사용하여 사이트맵 생성

sitemap.(js|ts)파일 규칙을 사용하면 URL 배열을 반환하는 기본 함수를 내보내 프로그래밍 방식으로 사이트맵을 생성 할 수 있습니다. TypeScript를 사용하는 경우 Sitemap유형을 사용할 수 있습니다.

// app/sitemap.ts
import { MetadataRoute } from 'next'

export default function sitemap(): MetadataRoute.Sitemap {
  return [
    {
      url: 'https://acme.com',
      lastModified: new Date(),
      changeFrequency: 'yearly',
      priority: 1,
    },
    {
      url: 'https://acme.com/about',
      lastModified: new Date(),
      changeFrequency: 'monthly',
      priority: 0.8,
    },
    {
      url: 'https://acme.com/blog',
      lastModified: new Date(),
      changeFrequency: 'weekly',
      priority: 0.5,
    },
  ]
}
acme.com/sitemap.xml

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://acme.com</loc>
    <lastmod>2023-04-06T15:02:24.021Z</lastmod>
    <changefreq>yearly</changefreq>
    <priority>1</priority>
  </url>
  <url>
    <loc>https://acme.com/about</loc>
    <lastmod>2023-04-06T15:02:24.021Z</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.8</priority>
  </url>
  <url>
    <loc>https://acme.com/blog</loc>
    <lastmod>2023-04-06T15:02:24.021Z</lastmod>
    <changefreq>weekly</changefreq>
    <priority>0.5</priority>
  </url>
</urlset>

2.1 여러 페이지(데이터)를 map과 함께 사이트맵 생성

// contentExample.json

{
  "list": [
    {
      "date": "2024-01-11",
      "image_url": "https://picsum.photos/360/180",
      "title": "Understanding React.js Hooks: A Comprehensive Guide",
      "description": "Dive into the world of React.js hooks with our in-depth guide. Learn how to effectively use useState, useEffect, and custom hooks to build dynamic and responsive applications.",
      "link_slug": "1"
    },
    {
      "date": "2024-01-11",
      "image_url": "https://picsum.photos/200/200",
      "title": "Understanding React.js Hooks: A Comprehensive Guide",
      "description": "Dive into the world of React.js hooks with our in-depth guide. Learn how to effectively use useState, useEffect, and custom hooks to build dynamic and responsive applications.",
      "link_slug": "2"
    },
    {
      "date": "2024-01-11",
      "image_url": "https://picsum.photos/200/200",
      "title": "Understanding React.js Hooks: A Comprehensive Guide",
      "description": "Dive into the world of React.js hooks with our in-depth guide. Learn how to effectively use useState, useEffect, and custom hooks to build dynamic and responsive applications.",
      "link_slug": "3"
    },
    {
      "date": "2024-01-11",
      "image_url": "https://picsum.photos/200/200",
      "title": "Understanding React.js Hooks: A Comprehensive Guide",
      "description": "Dive into the world of React.js hooks with our in-depth guide. Learn how to effectively use useState, useEffect, and custom hooks to build dynamic and responsive applications.",
      "link_slug": "4"
    }
  ],
  "blog": {
    "slug": "meta-title-is-same-with-slug",
    "metaTitle": "Meta Title is same with slug",
    "metaDescription": "meta-desription 150-160",
    "title": "Title blog",
    "description": "<div class='post-content'><p>Smart home technology has been rapidly evolving, with new innovations appearing every year. In this post, we'll explore the latest trends and predict where the industry is headed.</p><h2>Current Trends</h2><p>One of the most significant current trends in smart home technology is the integration of AI assistants. Devices like smart speakers and smart displays are becoming central control hubs for the entire home.</p><h2>The Future of Smart Homes</h2><p>Looking ahead, we can expect smart homes to become even more interconnected. The Internet of Things (IoT) will enable devices to communicate with each other seamlessly, creating a truly automated home environment.</p><h2>Conclusion</h2><p>As we continue to integrate technology into our homes, the possibilities for convenience, security, and energy efficiency are endless. The future of smart home technology is bright, and we can't wait to see what's next.</p><img src='smart-home.jpg' alt='Smart Home Technology'></div>",
    "image": "http://example.com/image.jpg",
    "category": "seo",
    "tags": ["seo", "develop", "exaple"],
    "datePublished": "2015-09-20",
    "dateCreated": "2015-09-20",
    "dateModified": "2015-09-20",
    "author": {
      "@type": "Person",
      "name": "Steve",
      "email": "info@xxx.com",
      "sns": "http://www.example.com"
    }
  }
}

}
tagData.json";

{
  "arrary": [
    {
      "markdown": 1,
      "code": 1,
      "features": 1,
      "next-js": 6,
      "math": 1,
      "ols": 1,
      "github": 1,
      "guide": 5,
      "tailwind": 3,
      "holiday": 1,
      "canada": 1,
      "images": 1,
      "feature": 2,
      "writings": 1,
      "book": 1,
      "reflection": 1,
      "multi-author": 1
    }
  ],
  "object": {
    "markdown": 1,
    "code": 1,
    "features": 1,
    "next-js": 6,
    "math": 1,
    "ols": 1,
    "github": 1,
    "guide": 5,
    "tailwind": 3,
    "holiday": 1,
    "canada": 1,
    "images": 1,
    "feature": 2,
    "writings": 1,
    "book": 1,
    "reflection": 1,
    "multi-author": 1
  }
}
// app/sitemap.ts
import { MetadataRoute } from "next";
import contentExample from "@/src/data/contentExample.json";
import tagData from "@/src/data/tag-data.json";

export default function sitemap(): MetadataRoute.Sitemap {
  const blogs = contentExample.list.map((blog) => ({
    url: `${process.env.SITENAME}/blog/${blog.link_slug}`,
    lastModified: blog.date,
  }));

  const tags = Object.keys(tagData.object).map((tag): any => ({
    url: `${process.env.SITENAME}/tag/${tag}`,
    lastModified: new Date(),
  }));

  return [
    {
      url: process.env.SITENAME,
      lastModified: new Date(),
      changeFrequency: "yearly",
      priority: 1,
    },
    {
      url: `${process.env.SITENAME}/about`,
      lastModified: new Date(),
      changeFrequency: "monthly",
      priority: 0.8,
    },
    {
      url: `${process.env.SITENAME}/blog`,
      lastModified: new Date(),
      changeFrequency: "daily",
      priority: 0.5,
    },
    {
      url: `${process.env.SITENAME}/tags`,
      lastModified: new Date(),
      changeFrequency: "weekly",
      priority: 0.5,
    },
    ...blogs,
    ...tags,
  ];
}

4. 여러 사이트맵 생성

단일 사이트맵은 대부분의 애플리케이션에서 작동합니다. 대규모 웹 애플리케이션의 경우 사이트맵을 여러 파일로 분할해야 할 수도 있습니다.

여러 사이트맵을 만드는 방법에는 두 가지가 있습니다.

예를 들어 를 사용하여 사이트맵을 분할하려면 generateSitemaps사이트맵이 포함된 개체 배열을 반환합니다 id. 그런 다음, 이를 사용하여 id고유한 사이트맵을 생성하세요.

app/product/sitemap.ts

import { BASE_URL } from '@/app/lib/constants'

export async function generateSitemaps() {
  // Fetch the total number of products and calculate the number of sitemaps needed
  return [{ id: 0 }, { id: 1 }, { id: 2 }, { id: 3 }]
}

export default async function sitemap({
  id,
}: {
  id: number
}): Promise<MetadataRoute.Sitemap> {
  // Google's limit is 50,000 URLs per sitemap
  const start = id * 50000
  const end = start + 50000
  const products = await getProducts(
    `SELECT id, date FROM products WHERE id BETWEEN ${start} AND ${end}`
  )
  return products.map((product) => ({
    url: `${BASE_URL}/product/${id}`,
    lastModified: product.date,
  }))
}

프로덕션 환경에서는 생성된 사이트맵을 에서 사용할 수 있습니다 /.../sitemap/\[id\].xml. 예를 들어,/product/sitemap/1.xml.

개발 중에는 생성된 사이트맵을 에서 볼 수 있습니다 /.../sitemap.xml/\[id\]. 예를 들어, /product/sitemap.xml/1. 이 차이는 일시적이며 제작 형식을 따릅니다.

자세한 내용은 generateSitemapsAPI 참조를 확인하세요 .

FAQs

물론, 다음은 Next.js에서 Sitemap과 관련된 다섯 가지 질문과 답변입니다:

  1. Q: Next.js에서 Sitemap은 무엇이고 왜 필요한가요?
    • A: Sitemap은 웹 페이지의 구조를 검색 엔진에 알려주는 XML 파일로, 검색 엔진 최적화(SEO)에 도움을 줍니다. Next.js에서는 next-sitemap과 같은 라이브러리를 사용하여 쉽게 Sitemap을 생성할 수 있습니다.
  2. Q: next-sitemap을 13버전 이하에서는 어떻게 설치하고 설정할 수 있나요?
    • A: next-sitemap은 npm을 통해 설치할 수 있습니다. 다음과 같이 설치한 후 next.config.js 파일을 만들어 설정을 추가합니다.
    • // next.config.js const withSitemap = require('next-sitemap'); module.exports = withSitemap({ // Sitemap 옵션들을 설정합니다. });
    • npm install next-sitemap
  3. Q: 그럼 13버전 이하에서는 next-sitemap과 함께 Sitemap에 페이지를 추가하는 방법은 무엇인가요?
    • A: next-sitemap에서는 siteMap 옵션을 통해 추가할 페이지를 정의할 수 있습니다. 예를 들어, 모든 동적 라우트를 추가하려면 다음과 같이 설정할 수 있습니다:
    • module.exports = withSitemap({ siteMap: [ // 여기에 추가할 페이지들을 나열합니다. ], });
  4. Q: 정적 경로와 동적 경로를 Sitemap에 어떻게 추가하나요?
    • A: 정적 경로는 직접 나열하고, 동적 경로는 getServerSideProps 또는 getStaticProps를 사용하여 데이터를 가져오면서 Sitemap에 추가할 수 있습니다. 예를 들어, 동적 경로를 추가하려면 다음과 같이 할 수 있습니다:
    • module.exports = withSitemap({ siteMap: [ '/static-page', { route: '/dynamic/[id]', lastmod: '2024-01-17', // 변경된 날짜 }, ], });
  5. Q: Sitemap을 생성한 후 어떻게 업데이트하고 검색 엔진에 제출하나요?
    • A: Sitemap을 업데이트하려면 빌드 스크립트에 명령을 추가하거나 CI/CD 도구를 사용할 수 있습니다. 업데이트 후에는 Google Search Console과 같은 도구를 사용하여 검색 엔진에 Sitemap을 제출할 수 있습니다. 검색 엔진은 주기적으로 Sitemap을 확인하므로 즉시 반영되지 않을 수 있습니다.

공식 문서

https://nextjs.org/docs/app/api-reference/file-conventions/metadata/sitemap

반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.