Noob Front End Engineer Blog

Gatsby 記事テンプレート作成

Gatsby

2022-11-13

記事ページ作成しよう

今回のセクションでは記事ページの作成をしていきましょう。

参考:https://www.gatsbyjs.com/docs/tutorial/part-6/#task-create-blog-post-page-template ˜

テスト用の記事データを作成する

Gatsbyでは

Contentful
などの外部のサービスと連携して、記事データを管理することもできるのですが、
このハンズオンでは記事データを
MDX
ファイルで保持するようにしています。

このセクションでは簡単な使用法のみの紹介になりますが、

MDX
形式は通常の
MD
形式と違い、作成したReactコンポーネントを呼び出して使用することができ、記事の自由度がかなり上がります。
記事を書く人がReactを扱える技術者であれば、有力な選択肢として上がってくると思います。

では、実際にテストの記事データを作成していきましょう。
下記2ファイルを追加してください。

src/posts/test01.mdx
---
title: test 01
slug: test-01
description: test post 01
tag: 
  - test tag 01
  - test tag 02
date: 2022-11-20
---

# test post 01 h1

test post 01 body
src/posts/test02.mdx
---
title: test 02
slug: test-02
description: test post 02
tag: 
  - test tag 01-2
  - test tag 02-2
date: 2022-11-21
---

# test post 02 h1

test post 02 body

これで記事のデータ自体は作成できたので、このデータを表示するためのテンプレートを用意していきましょう。

テンプレートを作成する

MDX
で作成した記事データを描画するためのテンプレートを作成していきましょう。
下記のような
/src/pages/{mdx.frontmatter__slug}.tsx
ファイルを作成して見ましょう。

src/pages/{mdx.frontmatter__slug}.tsx
import * as React from 'react'
import { graphql, HeadFC } from 'gatsby'

const BlogPost = ({data, children}) => {
  return (
    <div>
      <p>title: {data.mdx.frontmatter.title}</p>
      <p>description: {data.mdx.frontmatter.description}</p>
      <p>tag: {data.mdx.frontmatter.tag}</p>
      <p>date: {data.mdx.frontmatter.date}</p>
      <p>{children}</p>
    </div>
  )
}

export const query = graphql`
  query ($id: String) {
    mdx(id: {eq: $id}) {
      frontmatter {
        title
        description
        tag
        date(formatString: "YYYY-MM-DD")
      }
    }
  }
`

export const Head: HeadFC = () => <title>Blog</title>

export default BlogPost

Gatsbyでは

page
ディレクトリ配下にファイルを作成すると自動的にページが作成されますが、

それと似たような機能で、

page
配下に
{mdx.frontmatter__slug}.tsx
と言うファイルを作成することで
mdx
slug
と言う項目がURLのページが生成されます。

なので、この名称を

{mdx.frontmatter__test}.tsx
とすると
mdx
ファイル内の
test
と言う項目がURLになります!

再度

npm run develop
を実行して http://localhost:8000/blog/test-01 を開くと記事を開くことができると思います!

記事テンプレートの解説

下記部分が先程紹介した

page query
になります。

id
を引数として渡していますが、今回の場合は明示的に渡している訳ではなく自動で渡してくれます。

export const query = graphql`
  query ($id: String) {
    mdx(id: {eq: $id}) {
      frontmatter {
        title
        description
        tag
        date(formatString: "YYYY-MM-DD")
      }
    }
  }
`

上記クエリを実行することで

title
等の情報を取得してきてくれます。

このクエリで取得してきたデータは、下記箇所の第一引数(

data
)に渡ってきます。

第二引数(

children
)には
mdx
ファイルのコンテンツ部分(
body
)が渡ってきます。

const BlogPost = ({data, children}) => {
  return (
    <div>
      <p>title: {data.mdx.frontmatter.title}</p>
      <p>description: {data.mdx.frontmatter.description}</p>
      <p>tag: {data.mdx.frontmatter.tag}</p>
      <p>date: {data.mdx.frontmatter.date}</p>
      <p>{children}</p>
    </div>
  )
}

型エラーの対応

この状態だと、引数の

data
,
children
の箇所が型エラーになってしまいます。こちらのエラーも解決していきましょう。

目次