Next.jsとhygraph(Graph CMS)とMDXを使ってブログを作成

せっかくブログ作ったので記事投稿します。

継続が苦手なのですぐ飽きそうなのですが、モチベ高いうちにやりますw

そして、プライベートでもジム💪に行きだしましたが、まだ1週間1回ペースなので2回ペースにあげたいところ・・・

本題

このブログはNext.jsとhygraphで作っており、そのときにやったことをメモがてら書こうと思います。

hygraphの導入前は、Next.js でMDXを利用してMarkdownを書いていました。

ただ、記事を更新するためにソースコードをイジる必要があり面倒だなとおもってたので、 hygraphという外部CMSを導入しました。

その際に、hygraphでmarkdownを書いてそれをNext.jsで描画するのに少し躓いたので、対応した方法をの書き残します。

hygraphから受け取ったmarkdownを描画する

Next.jsで .mdx ファイルを直接書いていた頃は仕組み的に楽だったのですが、 外部APIからmarkdownを受け取って表示しようと思うと一筋縄でいけませんでした。

外部からAPIを受け取るときは next-mdx-remote を使う必要がありました。

大分省略していますが、下記はイメージです。

getStaticProps で Markdown を serialize して <MDXRemote> に渡しています。

import { getSdk } from '@/graphql/graphql'
import { GraphQLClient } from 'graphql-request'
import { GetStaticProps } from 'next'
import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote'
import { serialize } from 'next-mdx-remote/serialize'

interface Props {
  mdxSource: MDXRemoteSerializeResult
}

const Slug = (props: Props) => {
  return (
    <div>
      <MDXRemote {...props.mdxSource} />
    </div>
  )
}

export default Slug

export const getStaticProps: GetStaticProps = async (context) => {
  const graphQLClient = new GraphQLClient('XXXXXXXXXXXXXXXX')
  const client = getSdk(graphQLClient)
  const data = await client.getArticle({
    slug: context?.params?.slug?.toString(),
  })
  const mdxSource = await serialize(data.article?.body ?? '', {
    mdxOptions: {
      remarkPlugins: [],
      rehypePlugins: [],
    },
  })
  return {
    props: {
      mdxSource,
    },
  }
}

結果的に .mdx ファイルを使うことがなくなり、 .tsx ファイルにできたので補完も効くようになり便利になりました。

SSGでビルド

ブログへのアクセス時に毎回APIで記事を取得してくると遅いので、 Next.jsのビルド時に先にページを生成することにしました。

これは簡単で、 ビルド時に、全記事のpathを取得して、getStaticPathsに渡すだけでした。 下記はイメージです。

export const getStaticPaths = async () => {
  const graphQLClient = new GraphQLClient(XXXXXXXXXXXXXXXXXXX)
  const client = getSdk(graphQLClient)
  const data = await client.getArticleSlugs()
  return {
    paths: data.articles.map((article) => ({ params: { slug: article.slug } })),
    fallback: false,
  }
}

デプロイ自動化

ここまででブログの描画はできているのですが、 hygraphで記事を書いてから、Next.jsを手動でビルドする必要がありました。

hygraphで記事を書いたら自動でビルド&デプロイできないかなーと思ってたらありました! 下記の記事を見ると詳細がわかるのでおすすめです。

https://hygraph.com/docs/guides/webhooks/trigger-static-build

一応、簡単に概要を書くとWebhookを使って実現できます。

  1. Vercel でデプロイ用のwebhookを作成する
  2. hygraph で記事更新の際に、1を呼ぶように設定

これだけでできました。

自分はホスティングにVercelを使っていますが、他のホスティングサービスでも、webhookを作れるところであれば同じような事ができると思います。