November 11, 2020
Gatsby + Contentfulのブログ記事をMDXで書く方法
マークダウン記法は、簡単に文章構造を明示できる上、htmlも使えて非常に便利なんだけど、コンポーネントによってJSXも読み込めるMDXだとさらに便利。そこで今日は、Gatsby + Contentfulで構築したサイトのブログ記事を、MDXで書く方法をご紹介します。
Updated at December 24, 2020
皆さんご存知、マークダウン記法は、構文(#見出しなど)を簡単に書くことができる上、htmlも使えて非常に便利なんだけど、コンポーネントによってJSXも読み込めるMDXだとさらに便利。
そこで今日は、GatsbyJS + Contentfulで構築したサイトのブログ記事を、MDXで書く方法をご紹介します。
MDXとは?
MDXは、マークダウンのドキュメントにJSXを記述できるマークダウンの進化版です。
独自に用意したコンポーネントをインポートすることで、コンテンツ内にJSXを埋め込むことが出来るので、より簡単で便利に多様なコンテンツを作成することができます。
こんな感じで記述すると、
# Hello, *world*!
Below is an example of JSX embedded in Markdown. <br /> **Try and change the background color!**
<div style={{ padding: '20px', backgroundColor: 'tomato' }}>
<h3>This is JSX</h3>
</div>
こんな感じで表示できる。
一度、MDXでブログを書き始めると、もうマークダウンには戻れません😉
Gatsby + Contentful のサイトを用意
まずは、Gatsbyで作られたサイトに、Contentfulのコンテンツが読み込まれた状態があることを前提とします。
これから作る方は、下記のリンクを参考にしてください。
プラグインがあるので簡単です。
では例として、Contentful上でブログ記事の本文を入力する Content Model を作成していきましょう。
Content Model の名前は Body として進めます。
ここが重要!
Content Model は、まず Text を選択。
そして、ラジオボタンの Long Text を選択し、
Markdown を選んでください。
※ ContentfulにMDXはないけど、Markdown設定で大丈夫
そして、Contentful上で適当なコンテンツを入力しておきます。
ここでは Tomato
というコンポーネントを追加する予定で進めます。
コンテンツの例:
# MDXでブログを書くよ
<Tomato>Lorem ipsum dolor sit amet.</Tomato>
こんな感じ。
MDX用のプラグインを追加
次にコマンドラインで、GatsbyでMDXを使うためのプラグインをインストールします。
npmでインストール:
npm install gatsby-plugin-mdx @mdx-js/mdx @mdx-js/react
yarnでインストール:
yarn add gatsby-plugin-mdx @mdx-js/mdx @mdx-js/react
gatsby-config.jsに追記
gatsby-config.js
に、先ほどインストールした gatsby-plugin-mdx
を定義します。
{
resolve: `gatsby-plugin-mdx`,
options: {
gatsbyRemarkPlugins: [
// 他にRemarkプラグインがある場合はここに追加していく
],
},
},
詳しくは下記のページを参考にしてください。
GraphQLを確認
ここまでできたら、gatsby develop
してみましょう。
GraphQLを見てみると、childMDX
が追加されてるのが確認できます。
つまり、こんな感じでデータを取得できます。
export const query = graphql`
query getPost($id: String!) {
contentfulPost(contentful_id: { eq: $id }) {
title
description
body {
childMdx {
body
}
}
}
}
`
独自のコンポーネントを作成
components
フォルダに、shortcodes.js
ファイルを追加します。
ここにContentfulの方で書いた <Tomato>
コンポーネントを作ります。
import React from 'react'
const Tomato = ({ children }) => <div style={{ backgroundColor: `tomato` }}>{children}</div>
export { Tomato }
Markdownコンポーネントを作成
先ほど shortcodes.js
で作った Tomato
コンポーネントを、コンテンツ内で使えるように組み込みます。
まずは、components
フォルダに、Markdown.js
ファイルを追加。
import React from 'react'
import { MDXRenderer } from 'gatsby-plugin-mdx'
import { MDXProvider } from '@mdx-js/react'
import { Tomato } from './shortcodes'
const shortcodes = { Tomato }
const Markdown = ({ children }) => (
<div>
{/* MDXProviderで独自に作成したコンポーネントをマークダウンに追加 */}
<MDXProvider components={shortcodes}>
{/* MDXRendererでコンテンツを表示 */}
<MDXRenderer>{children}</MDXRenderer>
</MDXProvider>
</div>
)
export default Markdown
テンプレートにMarkdownコンポーネントを追加
最後に、ブログ記事のテンプレート内に、たった今作った Markdown
コンポーネントを追加。
const Post = ({ data }) => {
const { title, description, body } = data.contentfulPost
return <Markdown>{body.childMdx.body}</Markdown>
}
これで完成🙌
gatsby develop
してみると…。
問題なく背景が赤くなってますね!