고급 사용자 정의

Google 사이트맵 권장 사항을 읽을 때 다음과 같은 정보를 찾았습니다.

사이트맵에 표준 URL만 나열하세요. 페이지의 두 가지 버전이 있는 경우 사이트맵에 (Google에서 선택한) 표준만 나열합니다.

"표준"URL은 특정 엔터티의 "진정한 홈"입니다. 동일한 콘텐츠가 포함된 URL이 여러 개 있는 경우 검색 엔진에서 사용할 수 있도록 하나를 "표준"으로 표시해야 합니다.

이렇게 하지 않으면 Google에서 불이익을 주며 검색 결과 순위에 악영향을 미칠 수 있습니다 😬

내 블로그에서 게시물 URL의 형식은 /:category/:slug 입니다. 게시물이 여러 범주에 속할 수 있기 때문에 이것은 문제를 나타냅니다. 예를 들어 지금 읽고 있는 게시물은 다음 두 URL을 통해 도달할 수 있습니다.
/gatsby/seo-friendly-sitemap//seo/seo-friendly-sitemap/내 블로그의 게시물은 모두 MDX를 사용하여 작성되었습니다. 게시물의 머리말에는 다음과 같은 데이터가 있습니다.

---
title: "Generate an SEO-Friendly Sitemap for your Gatsby Site"
type: tutorial
publishedOn: 2020-03-09T09:30:00-0400
categories: ['gatsby', 'seo']
---


카테고리는 우선순위에 따라 나열되므로 첫 번째 카테고리는 항상 표준 URL을 형성해야 합니다.

문제는 분명합니다. 내 MDX 프론트매터에서 범주를 가져와 사이트맵에서 생성된 사이트를 필터링하는 데 사용해야 합니다. 기쁘게도 이것은 플러그인의 옵션입니다!

GraphQL로 데이터 쿼리gatsby-config.js 내에서 필요한 데이터를 가져오는 GraphQL 쿼리를 작성할 수 있습니다.

module.exports = {
    siteMetadata: {
    // ✂️
  },
  plugins: [
    {
      resolve: 'gatsby-plugin-sitemap',
      options: {
        exclude: ['/admin', '/confirmed'],
        query: `
          {
            site {
              siteMetadata {
                siteUrl
              }
            }
            allSitePage {
              edges {
                node {
                  path
                }
              }
            }
          }
        `,
      },
    },
  ],
};


기본적으로 플러그인은 이와 같은 쿼리를 사용하지만 덮어쓸 수 있습니다. 여기에서 siteUrl를 가져옵니다.

비표준 결과를 필터링하려면 먼저 올바른 데이터를 GraphQL에 노출해야 합니다!
allSitePage는 React 구성 요소를 src/pages에 넣거나 createPage API를 사용하여 생성된 모든 페이지의 인덱스입니다. 제 경우에는 createPage 를 사용하여 프로그래밍 방식으로 모든 기사/튜토리얼을 생성하고 있습니다.
createPage 내부의 일반적인 gatsby-node.js 호출은 다음과 같습니다.

createPage({
  path: pathname,
  component: path.resolve(...),
  context: {
    /* component props */
  },
});


Markdown 또는 MDX로 ​​블로그를 구축하고 있다면 이미 이것을 사용하여 페이지를 생성하고 있을 것입니다. 라이브에 path, 마운트에 component 및 구성 요소에 필요할 수 있는 일부 컨텍스트 데이터를 제공합니다. context에 전달된 모든 항목은 소품을 통해 component에서 사용할 수 있습니다.

다행스럽게도 context도 GraphQL에 노출되는 것으로 나타났습니다!
context에 새 데이터를 추가했습니다.

createPage({
  path: pathname,
  component: path.resolve(...),
  context: {
    isCanonical: currentCategory === canonicalCategory
  },
});

currentCategorycanonicalCategory 변수는 모든 데이터를 반복하고 이 페이지를 만드는 데 사용했기 때문에 이미 사용할 수 있었습니다.

이 데이터를 추가하면 내 query에서 gatsby-config.js에 전달된 GraphQL 쿼리를 업데이트할 수 있습니다.

query: `
  {
    site {
      siteMetadata {
        siteUrl
      }
    }
    allSitePage {
      edges {
        node {
          path
          context {
            isCanonical
          }
        }
      }
    }
  }
`,


페이지 필터링

이제 각 페이지의 "정식 상태"를 GraphQL에 노출하고 이를 gatsby-plugin-sitemap가 사용할 쿼리에 기록했습니다. 이 퍼즐의 마지막 조각: 이 쿼리된 데이터로 수행해야 하는 작업을 지정하기 위해 기본 "직렬 변환기"를 덮어씁니다.

다음과 같습니다.

{
  resolve: `gatsby-plugin-sitemap`,
  options: {
    exclude: ['/admin', '/confirmed'],
    query: /* ✂️ */,
    serialize: ({ site, allSitePage }) => {
      return allSitePage.edges
        .filter(({ node }) => (
          node.context.isCanonical !== false
        ))
        .map(({ node }) => {
          return {
            url: site.siteMetadata.siteUrl + node.path,
            changefreq: 'daily',
            priority: 0.7,
          };
        });
    },
  },
}

serializequery의 데이터를 "sitemappy"개체의 배열로 변환하는 함수입니다. 반환되는 항목은 사이트맵을 생성하기 위한 원시 데이터로 사용됩니다.

이제 GraphQL에서 지정했으므로 node.context.isCanonical에 액세스하여 중복 페이지를 필터링할 수 있습니다.
query에 내장된 serializegatsby-plugin-sitemap 탈출구를 사용하여 생성된 사이트맵을 훨씬 더 잘 제어할 수 있습니다. 또한 일부 페이지별 옵션을 미세 조정할 수 있습니다!

좋은 웹페이지 즐겨찾기