なつねこメモ

主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ

書いてあるコードは自己責任でご自由にどうぞ。記事本文の無断転載は禁止です。

2022/01/30

Next.js で MDX (Markdown React) を使って SSG したい

カテゴリー:ReactTypeScript

このブログは互換性重視なので、極力通常の Markdown を書いているのですが、例えばドキュメントサイトとかだと、
React Component を扱えると便利なケースがあります。
よくあるパターンだと、タブとかそういうものですね。

ということで、 Next.js で MDX を扱う方法。

今回は contentlayer と呼ばれるライブラリーをベースにします。
これは、 Markdown とか MDX、その他のコンテンツを良い感じに扱えるようにしてくれるラッパーみたいなライブラリです。
ということで、いつも通りインストールから。

$ yarn add contentlayer next-contentlayer

その後、 contentlayer.config.ts にスキーマを記述します。
ブログの場合は下のような感じ:

contentlayer.config.ts

import { defineDocumentType, makeSource } from "contentlayer/source-files";

const Blog = defineDocumentType({
  name: "Blog",
  filePathPattern: "blog/**/*.md",
  bodyType: "mdx",
  fields: {
    title: { type: "string", required: true },
    date: { type: "date", required: true },
  },
});

const config = makeSource({
  contentDirPath: "contents",
  documentTypes: [Blog],
  mdx: {
    remarkPlugins: [require("remark-gfm")],
    rehypePlugins: []
  },
});

export default config;

next.config.js もこんな感じ。

next.config.js

const { withContentlayer } = require("next-contentlayer");

module.exports = withContentlayer()({
  reactStrictMode: true,
  trailingSlash: true,
});

で、 pages/[...slug].tsx はこんな感じにする

pages/[...slug].tsx

import React from "react";
import { useMDXComponent } from "next-contentlayer/hooks";
import { allBlogs } from ".contentlayer/data";

import SomeComponent from "../components/SomeComponent";

const getStaticPaths = ...;
const getStaticProps = ...;

export default Entry = ({ entry }) => {
  const Component = useMDXComponent(entry.body.code);

  return (
    <>
      <Component components={{ SomeComponent }}/>
    </>
  );
}

こんな感じで使えます。
ということでメモでした。