Gatsbyでサムネイルを表示する方法についてまとめました。
いつもご利用ありがとうございます。
この記事には広告が掲載されており、その広告費によって運営しています。
Gatsby でマークダウンで記事を書く際に、サムネイルを設定しようとしたら思いの他時間がかかったので、記事にしました。node-config でサムネイルの graphql に対して相対パスの指定をする必要がありました。
前提
スターターで、以下のものを使用しています。
つまり、以下のようなプラグインはすでに入っている前提で進めていきます。
gatsby-plugin-sharp gatsby-source-filesystem gatsby-transformer-sharp
最後に表示するときに使う gatsby-image をインストールします。
npm install --save gatsby-image
マークダウンと同じディレクトリに画像を設置
今回は、
/content/blog/new-beginnings/index.md
/content/blog/new-beginnings/top.jpg
このように画像と md ファイルが設置されています。
md ファイルにサムネイルの項目を追加する
thumbnail を相対パスで指定します。今回は同じディレクトリにあるので、ファイル名だけです。
---
title: New Beginnings
date: "2015-05-28T22:40:32.169Z"
description: 最初にあるmdファイルを編集してます
thumbnail: "top.jpg"
---
gatsby-node.js を編集する
/gatsby-node.js の下の方に、
Frontmatter に関する定義がされている場所を以下のように変更します。
type Frontmatter {
title: String
description: String
date: Date @dateformat
thumbnail: File @fileByRelativePath
}
thumbnail が File であることを定義します。
そうすることによって、後述するファイル用(sharp)graphql が使えるようになります。
これを書かないと、childImageSharp を使おうとするとエラーになります。
ちなみに File ではなく、String を指定すると以下のようなエラーになります。
There was an error in your GraphQL query:
Field "thumbnail" must not have a selection since type "String" has no subfields.
This can happen if you e.g. accidentally added { } to the field "thumbnail". If you didn't expect "thumbnail" to be of type "String" make sure that your input source
and/or plugin is correct.
そして、@fileByRelativePath によって、画像のファイルの位置が相対パスであることを定義します。
これを書かないと、相対パスでちゃんと画像の位置を指定しても、childImageSharpがnullになります。
僕はこれを知るために3時間かかったので記事にしています(汗)
一覧の graphQL
thumbnail の項目を追加
export const pageQuery = graphql`
query {
site {
siteMetadata {
title
}
}
allMarkdownRemark(
sort: { fields: [frontmatter___date], order: DESC }
filter: { fileAbsolutePath: { regex: "/(blog)/" } }
) {
nodes {
excerpt
fields {
slug
}
frontmatter {
date(formatString: "MMMM DD, YYYY")
title
description
thumbnail {
childImageSharp {
fluid(maxWidth: 1280) {
...GatsbyImageSharpFluid
}
}
}
}
}
}
}
`
表示の書き方
graphQL で取得した画像を、Image の fluid(gatsby-image)に指定する。
画像を設定しない記事もあるかもしれないので、一応 optional をつけてます。
import Image from "gatsby-image"
const BlogIndex = ({ data, location }) => {
const siteTitle = data.site.siteMetadata?.title || `Title`
const posts = data.allMarkdownRemark.nodes
return (
<div>
{posts.map(post => {
const title = post.frontmatter.title || post.fields.slug
const thumbnail = post.frontmatter.thumbnail?.childImageSharp.fluid
return (
<div>
<Image fluid={thumbnail} alt="ポッポテニス画像" />
<Link to={post.fields.slug} itemProp="url">
<span itemProp="headline">{title}</span>
</Link>
</div>
)
})}
</div>
)
}
export default BlogIndex
まとめ
以上です。
スターターがアップデートをしたのか分かりませんが、gatsby-node のところ、情報 がなくて結構ハマりました。
誰かの参考になれば幸いです。
それでは!!!
質問、誤記などあれば Twitter などでご指摘よろしくおねがいします!
人気記事
PHP7.4 + Laravel6 のプロジェクトを AWS EC2 にデプロイする
関連記事