Gatsby.js スタティックサイトのチュートリアル Part 5
Gatsby.jsでMDXを使用したブログサイトを作成するチュートリアルのPart5です。いよいよブログページを段階的に作成していきます。最終的には各ブログポストへのリンクがあるブログページにしていきますが、まずはブログポストの一覧を表示できるようにしていきます。
MDXブログポストの作成
いくつかブログポストを作成しておきます。プロジェクトの最上階層にblogフォルダを作成してそこにMDXファイルを作成します。
ローカルにポストファイルを作成しているので、Gatsbyデータレイヤで扱うためにPart3でインストールしておいたgatsby-source-filesystemプラグインを使用します。blogフォルダ内のファイルを検索できるようにgatsby-config.jsを下記のように変更します。
gatsby-config.js
module.exports = {
siteMetadata: {
title: `Gatsby Static Site Tutorial`,
},
plugins: [
`gatsby-plugin-image`,
`gatsby-plugin-sharp`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: `blog`,
path: `${__dirname}/blog`,
}
},
],
};
コンフィグファイルを変更したのでローカルサーバーを再起動しておきましょう。
ページクエリ
GraphiQLでブログポストのファイル名を取得してみましょう。複数のファイルを取得するにはallFileフィールドを使用します。nodes → name と選択すればファイル名を取得できます。
下記のようにデータを取得できます。
{
"data": {
"allFile": {
"nodes": [
{
"name": "fifth-post"
},
{
"name": "fitst-post"
},
{
"name": "fourth-post"
},
{
"name": "second-post"
},
{
"name": "sixth-post"
},
{
"name": "third-post"
}
]
}
},
"extensions": {}
}
このデータをブログページに使用します。ページコンポーネントにGraphQLを使用する場合は構成ブロックでGraphQLを使用するのとは少し違った文法になります。blog.jsを下記のように変更します。
src/pages/blog.js
import * as React from 'react'
import { graphql } from 'gatsby'
import Layout from '../components/layout'
import Seo from '../components/seo'
const BlogPage = ({ data }) => {
return (
<Layout pageTitle="Blog">
<ul>
{
data.allFile.nodes.map(node => (
<li key={node.name}>
{node.name}
</li>
))
}
</ul>
</Layout>
)
}
export const query = graphql`
query {
allFile {
nodes {
name
}
}
}
`
export const Head = () => <Seo title="Blog" />
export default BlogPage
まずimportでgraphqlを読み込みます。GraphiQLで作成したクエリをquery変数に格納します。BlogPageコンポーネントにpropでdataを受け渡しています。JavaScriptのarray.map()メソッドでリストを表示します。
gatsby-source-filesystemプラグインを使用してブログポストのファイル名を表示できましたが、このままではファイル内のコンテンツを表示することができません。ファイル内のコンテンツを表示するためにはトランスフォーマープラグイン(transformer plugin)を使用してファイルを変換する必要があります。
このチュートリアルではMDXファイルを変換するのでgatsby-plugin-mdxプラグインを使用していきます。このプラグインは.mdxのファイルノードからMDXノードを作成し、GraphQLで検索できるフィールドを提供してくれます。
MDXファイルにマークダウンを追加する
それではそれぞれのブログポストにマークダウンを追加しておきます。フロントマター(frontmatter)にtitle、date、slugを記載し、マークダウンで本文を記載します。下記のように作成しておきます。本文は lorem ipsum でダミーテキストをいれておきます。
blog/first-post.mdx
---
title: "First Post"
date: "2024-04-01"
slug: "first-post"
---
# Neque convallis a cras semper auctor.
Mus mauris vitae ultricies leo integer malesuada nunc vel risus commodo viverra maecenas accumsan, lacus vel facilisis volutpat, est velit egestas dui? Sodales neque sodales ut etiam sit amet nisl!
blog/second-post.mdx
---
title: "Second Post"
date: "2024-04-02"
slug: "second-post"
---
# Nulla facilisi etiam dignissim diam quis!
Eget nunc scelerisque viverra mauris, in aliquam sem fringilla ut morbi tincidunt augue interdum velit euismod in pellentesque massa. Ac orci phasellus egestas tellus rutrum tellus pellentesque eu tincidunt tortor.
blog/third-post.mdx
---
title: "Third Post"
date: "2024-04-03"
slug: "third-post"
---
# Elit eget gravida cum sociis natoque?
Sed sed risus pretium quam vulputate dignissim suspendisse in est ante in nibh mauris, cursus mattis molestie a, iaculis. Nunc sed velit dignissim sodales ut eu sem integer vitae justo.
blog/fourth-post.mdx
---
title: "Fourth Post"
date: "2024-04-04"
slug: "fourth-post"
---
# Risus ultricies tristique nulla aliquet enim!
Diam volutpat commodo sed egestas egestas? Id porta nibh venenatis cras sed felis eget velit aliquet sagittis id consectetur purus ut faucibus pulvinar elementum integer enim neque, volutpat ac tincidunt.
blog/fifth-post.mdx
---
title: "Fifth Post"
date: "2024-04-05"
slug: "fifth-post"
---
# Adipiscing elit pellentesque habitant morbi tristique!
Nunc vel risus commodo viverra maecenas accumsan, lacus vel facilisis volutpat, est velit egestas dui, id ornare arcu odio? Id venenatis a, condimentum vitae sapien pellentesque habitant morbi tristique senectus.
blog/sixth-post.mdx
---
title: "Sixth Post"
date: "2024-04-06"
slug: "sixth-post"
---
# Enim, facilisis gravida neque convallis a?
Nisl rhoncus mattis rhoncus, urna neque viverra justo, nec ultrices dui sapien. Donec pretium vulputate sapien nec sagittis aliquam malesuada bibendum arcu vitae elementum curabitur vitae nunc sed velit dignissim!
ブログポストのコンテンツが用意ができました。
gatsby-plugin-mdxプラグインを使用してコンテンツを表示する
まずプラグインをインストールしておきましょう。CLIで下記コマンドを実行します。
npm install gatsby-plugin-mdx @mdx-js/react
gatsby-config.jsを下記のように変更します。
gatsby-config.js
module.exports = {
siteMetadata: {
title: `Gatsby Static Site Tutorial`,
},
plugins: [
`gatsby-plugin-image`,
`gatsby-plugin-sharp`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: `blog`,
path: `${__dirname}/blog`,
}
},
`gatsby-plugin-mdx`,
],
};
これでMDXファイルのコンテンツをGraphQLで検索することができるようになったのでGraphiQLでクエリを作成しましょう。
allMdxフィールドから必要な項目を選択していきます。ブログ形式では日付が新しい順に表示するのが一般的なので引数のsortを使用して日付が新しいものが上にくるように指定します。allMdx → sort: → frontmatter → date → DESC の順に選択します。
あとは表示する項目を選択します。nodes内でfrontmatter、id、excerptを選択し、さらにfrontmatter内のdateとtitleを選択します。
また、frontmatter → date 内の formatString: を指定することで日付の表示形式を選択できます。formatStringはJavaScriptのMoment.jsというライブラリで使用されている形式で指定できます。
クエリを実行すると取得できるデータが表示されます。
それではGraphiQLで作成したクエリを使用してblog.jsを下記のように変更します。
src/pages/blog.js
import * as React from 'react'
import { graphql } from 'gatsby'
import Layout from '../components/layout'
import Seo from '../components/seo'
const BlogPage = ({ data }) => {
return (
<Layout pageTitle="Blog">
{
data.allMdx.nodes.map((node) => (
<article key={node.id}>
<h2>{node.frontmatter.title}</h2>
<p>Posted: {node.frontmatter.date}</p>
<p>{node.excerpt}</p>
</article>
))
}
</Layout>
)
}
export const query = graphql`
query {
allMdx(sort: { frontmatter: { date: DESC }}) {
nodes {
frontmatter {
title
date(formatString: "MMMM D, YYYY")
}
id
excerpt
}
}
}
`
export const Head = () => <Seo title="Blog" />
export default BlogPage
ブログページの表示を確認します。
各記事のタイトル、日付、抜粋を表示できました。今回は以上です。