gotohayato.com

月(ダークモード)
太陽(ライトモード)

Gatsby で gatsby-theme-blog を使うときの tips

2020/01/28JavaScriptJAMstackSSGReactGatsby

Gatsby 公式のブログ用テーマ gatsby-theme-blog を使うときの tips です。

追記 2020/07/29: この説明は gatsby-theme-blog1.x 系に対するものです。 2020 年 7 月にリリースされた gatsby-theme-blog2.x にはあてはあまらない部分のあるのでご注意ください。

Gatsby の theme システムには CMS によくある高機能な拡張機能が備わっているのですが、 gatsby-theme-blog はおそらくほぼそのまま使うことを想定して作られています。 あるいは gatsby-theme-blog は単純に reference implementation なのかもしれません。

そんな gatsby-theme-blog を私なりに工夫して使い倒してみたので、その tips をここにまとめておきます。

できるだけ gatsby-theme-blog に特化したことだけを書き、 Gatsby 全般に共通のことは書かないようにします。

尚この記事を書いているときの各ライブラリの最新バージョンは次のとおりです。

  • react: 16.12.0
  • gatsby: 2.19.5
  • gatsby-theme-blog: 1.2.32

最初にかんたんに用語の説明をします。

用語の説明

Gatsby とは?

Gatsby は React ベースのウェブサイト・ウェブアプリ制作用のフレームワークです。

カテゴリとしては「スタティックサイトジェネレータ」(静的サイトジェネレータ)や「 JAMstack フレームワーク」等に分類されるでしょうか。

追記 2020/05/26: 静的サイトジェネレーターや JAMstack に興味がある方には次の記事がご参考になるかと思います。

gatsby-theme-blog とは?

gatsby-theme-blog (The Gatsby Blog theme) は Gatsby 公式のブログ作成用テーマです。

そのまま使った場合、投稿の一覧ページ(ページャなし)と詳細ページだけからなる非常にシンプルなブログサイトを作ることができます。

Gatsby の theme システムには他のテーマをベーステーマとして利用できる仕組みが用意されています。 gatsby-theme-blog の場合は同じく Gatsby 公式の gatsby-theme-blog-core をベーステーマとして使用しています。

では本題です。

gatsby-theme-blog を使うときの tips

tips 01. gatsby-theme-blog を使ってブログ制作を始めたい

gatsby-theme-blog を使ってブログを始めるときは、公式の説明のとおりスターター gatsby-starter-blog-theme を使う方法がかんたんです。

gatsby new my-themed-blog https://github.com/gatsbyjs/gatsby-starter-blog-theme

my-themed-blog にはファイル一式のルートとなるディレクトリ名を指定します。

gatsby new コマンドを実行したら、ファイル gatsby-config.js を編集して gatsby-theme-blog のテーマオプションと siteMetadata を設定すれば、後は .md ファイルを追加していくだけですぐにブログを作り始めることができます。

この記事を書いている時点で gatsby-theme-blog のテーマオプションは次のとおりです。

  • basePath: ブログのルート URL 。ここに全投稿の一覧ページが表示される。デフォルトは /
  • contentPath: ブログの投稿の .md ファイルを配置するパス。デフォルトは content/posts
  • assetPath: アセットファイルを配置するパス。デフォルトは content/assets
  • mdx: gatsby-plugin-mdx を設定するかどうか。デフォルトは true

基本的にはデフォルト値のままで使えます。 何かしらの事情が無いかぎりデフォルト値で使えばよいでしょう。

siteMetadata の有効な要素には次のものがあります。

  • title: ブログのタイトル。ヘッダーに表示される。
  • author: avatar の alt や OGP の twitter:creator タグの値に使われる。
  • description: meta description タグの値。
  • social: GitHub や Twitter 等のアカウント。 2 つの要素 nameurl を持つオブジェクトの配列を入れる。

.md ファイルでは frontmatter が利用できます。 frontmatter とは、次に示すような、 .md ファイルの先頭に置けるメタ情報の記述です。

---
title: こんにちは
slug: /post/hello-world
date: 2020-05-27
keywords:
  - あいさつ
  - 日本語
---

これは本文です。

frontmatter 参考:

tips 02. 一覧ページのパスを変えたい

ブログ投稿の一覧ページのパスを変えたいときは、テーマオプション basePath を変更すれば OK です。

// gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: `gatsby-theme-blog`,
      options: {
        basePath: `/archive`,
      },
    },
  ],
}

tips 03. 新しいノードタイプを追加したい

ブログ投稿以外のノードタイプを追加したいときは、通常の Gatsby サイトと同じように、 gatsby-node.js 内に createSchemaCustomization() を書いてその中で createTypes() でノード定義を追加すれば OK です。

次のコードは StaticPage というインタフェースと MdxStaticPage というノードタイプを定義するサンプルです:

exports.createSchemaCustomization = ({ actions, schema }) => {

  // インタフェース `StaticPage` とタイプ `MdxStaticPage` を定義する
  createTypes(`
    interface StaticPage @nodeInterface {
      id: ID!
      title: String!
      slug: String!
      excerpt: String!
      body: String!
    }
  `)

  createTypes(
    schema.buildObjectType({
      name: `MdxStaticPage`,
      fields: {
        id: { type: `ID!` },
        title: { type: `String!` },
        slug: { type: `String!` },
        excerpt: {
          type: `String!`,
          args: {
            pruneLength: {
              type: `Int`,
              defaultValue: 140,
            },
          },
          resolve: mdxResolverPassthrough(`excerpt`),
        },
        body: {
          type: `String!`,
          resolve: mdxResolverPassthrough(`body`),
        },
      },
      interfaces: [`Node`, `StaticPage`],
    })
  )

}

tips 04. 固定ページを作りたい 

固定ページを作りたいときは、通常の Gatsby サイトと同じように gatsby-node.js 内に createPages() を書いて、その中で createPage() でページを追加すれば OK です。

ブログ投稿の一覧ページ・詳細ページと同じレイアウトを適用したい場合は、パッケージ gatsby-theme-blog 内の src/components/ 以下の posts.jspost.js を参考にします。

post.js:

import React from "react"
import { Styled, css } from "theme-ui"

import PostFooter from "../components/post-footer"
import Layout from "../components/layout"
import SEO from "../components/seo"
import { MDXRenderer } from "gatsby-plugin-mdx"

const Post = ({
  data: {
    post,
    site: {
      siteMetadata: { title },
    },
  },
  location,
  previous,
  next,
}) => (
  <Layout location={location} title={title}>
    <SEO title={post.title} description={post.excerpt} />
    <main>
      <Styled.h1>{post.title}</Styled.h1>
      <Styled.p
        css={css({
          fontSize: 1,
          mt: -3,
          mb: 3,
        })}
      >
        {post.date}
      </Styled.p>
      <MDXRenderer>{post.body}</MDXRenderer>
    </main>
    <PostFooter {...{ previous, next }} />
  </Layout>
)

export default Post

tips 05. プロフィールコンポーネントのレイアウトを変えたい

プロフィールコンポーネントのレイアウトを変えたいときは、 gatsby-theme-blogBio コンポーネントをシャドーイングで変更すれば OK です。 Bio コンポーネントは gatsby-theme-blog パッケージの中の src/components/bio.js で定義されています。

ちなみに、プロフィールの本文だけを変更したいときは、その隣にある BioContent (bio-content.js) をシャドーイングします。 プロフィール画像(「アバター」)を設定したいときは、 content/assets/ 以下に avatar.[jpeg|jpg|gif|png] (拡張子はいずれか)というファイル名で画像ファイルを設置すれば OK です。

tips 06. タグページ(タグ別の投稿一覧ページ)を作りたい

gatsby-theme-blog では frontmatter でのタグをサポートしていますが、タグページ(タグ別の投稿一覧ページ)が自動で作られるわけではありません。 タグページを作りたい場合は自分で作成する必要があります。

タグページを追加するには、一般に Gatsby でページを追加したいときと同じように createPages() の中で createPage() を書けば OK です。

タグは単なる文字列なので、タグデータは投稿のノードタイプ BlogPost から group を使って抽出します。

exports.createPages = async ({ graphql, actions, reporter }) => {
  const { createPage, createRedirect } = actions

  const result = await graphql(`
    {
      allBlogPost {
        group(field: tags) {
          name: fieldValue
          totalCount
        }
      }
    }
  `)

  if (result.errors) {
    reporter.panic(result.errors)
  }

  const tags = result.data.allBlogPost.group
  tags.forEach(tag => {
    createPage({
      path: `/tags/${slugify(tag.name)}/`,
      component: PostTagPageTemplate,
      context: {
        name: tag.name,
      },
    })
  })

}

tips 07. 投稿一覧ページをカスタマイズしたい

投稿一覧ページをカスタマイズしたいときは、 gatsby-theme-blogposts.js コンポーネントをシャドーイングします。 posts.jsgatsby-theme-blog パッケージ内の src/components/ 以下にあります。

投稿一覧ページのテンプレートだけでなく GraphQL クエリごと丸ごと変更したいときは、 gatsby-theme-blog-coreposts-query.js テンプレートをシャドーイングします。

posts-query.jsgatsby-theme-blog-core パッケージ内の src/templates/ 以下にあります。

tips 08. 投稿詳細ページをカスタマイズしたい

投稿詳細ページも投稿一覧ページと同様にカスタマイズできます。

テンプレートをカスタマイズしたしときは、 gatsby-theme-blogpost.js コンポーネントをシャドーイングします。 post.jsgatsby-theme-blog パッケージ内の src/components/ 以下にあります。

投稿一覧ページのテンプレートだけでなく GraphQL クエリごと丸ごと変更したいときは、 gatsby-theme-blog-corepost-query.js テンプレートをシャドーイングします。

post-query.jsgatsby-theme-blog-core パッケージ内の src/templates/ 以下にあります。

tips 09. 日付のフォーマットを変更したい

投稿一覧ページと投稿詳細ページの投稿日付のフォーマットは、デフォルトでは日本人に馴染みの薄い 月 日, 年 になっています。 これを変更したいときは、 posts-query.jspost-query.js をシャドーイングして GraphQL クエリを変更します。

例えば次のようにすると 2020/05/27 といったフォーマットにできます。

export const query = graphql`
  query CustomedPostPageQuery($id: String!, $previousId: String, $nextId: String) {
    site {
      siteMetadata {
        title
        social {
          name
          url
        }
      }
    }
    blogPost(id: { eq: $id }) {
      id
      excerpt
      body
      slug
      title
      tags
      keywords
      date(formatString: "YYYY/MM/DD")
    }
  }
`

tips 10. オリジナルの 404 ページを設定したい

オリジナルの 404 ページを設定したいときは、 Gatsby サイトでの一般的な方法と同じで、 src/pages/404.js ファイルを作成すれば OK です。 このパス・名前でファイルを作成すれば Gatsby が自動的にそれを 404 ページに使用してくれます。

tips 11. CSS のスタイルを変更したい

gatsby-theme-blog はデフォルトで gatsby-plugin-theme-ui を通じて theme-ui を利用して CSS スタイルを作っています。

この CSS のスタイルを変更したいときは、 gatsby-plugin-theme-ui のコンポーネントをシャドーイングします。 変更したい箇所によっては gatsby-theme-bloggatsby-plugin-theme-ui のコンポーネントをシャドーイングしている部分をさらにシャドーイングする必要があります。

tips 12. テーマが生成するページにコンテキスト変数を追加したい

gatsby-theme-blog または gatsby-theme-blog-core が提供するページのコンテキスト変数を追加したいときは、 onCreatePage() を使います。

ただし、すでに作られたページに後からコンテキスト変数を追加することはできないので、 onCreatePage() の中で deletePage() で元のページをいったん削除してから、コンテキスト変数を追加した形で createPage() してページを再追加する必要があります。

const merge = require(`deepmerge`)

exports.onCreatePage = async ({ page, actions, getNode }) => {
  const { createPage, deletePage } = actions

  if (/* 対象ページでのみ true を返す条件式 */) {
    const node = getNode(page.context.id)
    deletePage(page)
    createPage(
      merge(
        {
          context: {
            tags: node.tags,
          },
        },
        page
      )
    )
  }
}

tips 13. <html>lang 属性を ja に変更したい

gatsby-theme-blog のデフォルトのテンプレートでは htmllang 属性が en になっています。

<html lang="en">

これは gatsby-theme-blogseo.js コンポーネントをシャドーイングすると変更することができます。

lang 属性を変更するためだけに seo.js をシャドーイングする必要があるのは面倒なので、今後 gatsby-theme-blog がメンテナンスされ続ければ、将来的にここはテーマオプションで変更できるようになる気がします)

tips 14. 画像が二重に表示されるバグをどうにかしたい

追記 2020/04/19: このバグは解消されたようです。

状況によっては gatsby-theme-blog を使っていると markdown 内の画像が 2 重に表示されてしまうことがあります。

これはバグなので近々解決される可能性があります。 当面の対応としては、 gatsby-config.jsgatsby-remark-images を明示的に読み込むことでバグを回避することができます。

関連イシュー:

tips 15. ソースコードを確認したい

gatsby-theme-blog を使うときにシャドーイングが必要になった場合なんかには、 gatsby-theme-blog のコードを確認しないと進められないことがあります。

gatsby-theme-blog のコードは Gatsby 本体のリポジトリの中にあります。

gatsby-theme-blog の親テーマである gatsby-theme-blog-core のコードも同じく Gatsby 本体のリポジトリの中にあります。

ということで、 Gatsby で gatsby-theme-blog を使うときの小ネタ集でした。

追記 2020/05/26

gatsby-theme-blog もその親テーマである gatsby-theme-blog-core も活発に開発が進んでおり、テーマオプションで設定できる項目や post ノードのフィールドがどんどん追加されていっています。 利用の際はぜひ最新の README も確認するようにしてください:


後藤隼人
ウェブサイト制作・ウェブアプリ開発やマーケティングをしています。
GitHub
© 2020 gotohayato.com
サイトについてタグアーカイブメッセージを送る