開発日誌

開発した時に躓いたこととかの記録

Next.js(app directory)でMarkdownを読み込む

やりたいこと

  • Next.jsのapp directoryモードで.mdファイルを読み込んでページの途中に表示するやつをやりたい

やり方

  • 公式にもやり方は書いてある
  • ただし上記の方法はapp directoryでは使えないのでapp dirへの移行方法を参考に改変
  • おおざっぱにいうとgetStaticPropsは不要になって、React Component自体をasyncにしてgetStaticPropsに詰めてたものはReact Component内でawaitで呼んでよくなった
  • 他は既存に同じ

  • インストール

npm install remark remark-html gray-matter
  • 実装
import styles from './page.module.scss'
import { remark } from 'remark'
import html from 'remark-html'
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'

const getMdData = async () => {
  const fullPath = path.join('./src/app/', 'content.md')
  const fileContents = fs.readFileSync(fullPath, 'utf8')

  const matterResult = matter(fileContents)

  const processedContent = await remark()
    .use(html)
    .process(matterResult.content)
  const contentHtml = processedContent.toString()

  return {
    fullPath,
    contentHtml,
    ...matterResult.data,
  }
}

const Home = async () => {
  const contentData = await getMdData()
  return (
    <main>
        <div dangerouslySetInnerHTML={{ __html: contentData.contentHtml }} />
    </main>
  )
}

export default Home

つぶやき

  • 今までの感覚からするとそこでasync/awaitしていいんすか!?って感じがあるが、確かにこの方がシンプルでいいかも
  • 脳死でやるとReact Componentのロジック部がすぐ肥大化しそうなのでガッツリ作るプロダクトではGETは別ファイルに記載とかにした方が良さそう
  • app directory、思ったより大きな変更っぽいのでもうちょっとちゃんとキャッチアップしようと思った
    • 名前の響き的に大きな変更だと思ってなかった、名前で判断してはいかんね