Gatsbyで前後記事のリンクを貼る方法

2021-08-04

リニューアル前からいろいろ調べていて『難しそうだなぁ』と思っていたのですが。

てきとうに実装したところまったく難しくなかったので備忘録がてら。

まずは gatsby-node.js です。

const path = require(`path`);

exports.createPages = async ({ actions: { createPage }, graphql }) => {
  const {
    data: {
      allMarkdownRemark: { edges },
    },
  } = await graphql(`
    {
      allMarkdownRemark(sort: { order: DESC, fields: frontmatter___date }) {
        edges {
          node {
            frontmatter {
              date
              slug
              title
            }
          }
        }
      }
    }
  `);
  const component = path.resolve(`src/pages/blog/_date/index.tsx`);

  edges.forEach(
    (
      {
        node: {
          frontmatter: { slug },
        },
      },
      index,
    ) => {
      createPage({
        component,
        context: {
          next: edges.find((_, edgeIndex) => index === edgeIndex + 1),
          prev: edges.find((_, edgeIndex) => index === edgeIndex - 1),
        },
        path: slug,
      });
    },
  );
};

普通にマークダウンファイルを GraphQL を通して取得してきて、そこからページを生成すると思うのですが。

その際に前後の記事情報も取得して context で流し込んでやってるだけです、簡単ですね。

続いてページコンポーネント側ですが。

type Edge = {
  node: {
    frontmatter: {
      date: string;
      slug: string;
      title: string;
    };
  };
};

export type DateProps = PageProps<
  Hoge,
  {
    next?: Edge;
    prev?: Edge;
  }
>;

function Date({
  pageContext: { next, prev },
}: DateProps): JSX.Element {
  ...
}

context として前後の記事情報が流れ込んでくるので、それをprops で取得してやればあとは煮るなり焼くなりです。

似たような感じでページャーとかも組めるんだろうなーと思いつつ、めんどくさいのでまだいいかな…。

Gatsby まだまだ理解できていないことだらけです。