Gatsby:イメージ(画像)を表示させるための作法
ダイナミックに読み込んで表示させる
これはいったい…?
デフォルトでトップページに貼られているスペースマン画像"gatsby-astronaut.png"。
このファイルはimagesフォルダの中にあって、それを読み込むトップページindex.jsは、
//index.js
<Image />
とだけある。
?????
どうやらcomponentsフォルダにあるimage.jsがハンドルしているようである(デフォルトで存在する)。
//components/image.js デフォルトのコード
import React from "react"
import { useStaticQuery, graphql } from "gatsby"
import Img from "gatsby-image"
const Image = () => {
const data = useStaticQuery(graphql`
query {
placeholderImage: file(relativePath: { eq: "gatsby-astronaut.png" }) {
childImageSharp {
fluid(maxWidth: 300) {
...GatsbyImageSharpFluid
}
}
}
}
`)
return <Img fluid={data.placeholderImage.childImageSharp.fluid} />
}
export default Image
このコードを超訳すると、
gatsby-astronaut.pngというファイル名に一致するものを探し出してきて(8行目、 eq: "gatsby-astronaut.png" )自動で画像を最適化しレスポンシブで表示しする。
さらに、dig down(追及)しないがLazy loadingまでやってくれる。ためしにgatsby-astronaut.pngを別のめっさ重い画像に取り換えてみて表示させると、ぼやけた状態からフェードインするようにハッキリした画像にスムーズに写り替わる。なかなか感動する。
したがって画像ファイルはすべてimagesフォルダに置いて、このgatsby-astronaut.pngというところを表示させたい画像ファイル名に変更して、表示させたいページ側で<Image />
タグを書くだけで済む。
しかしそれでは画像はひとつしか使えないではないか…。
解決方法
多くの方がすでに解決方法を。image.jsを次のように変更。
//components/image.js
import React from "react"
import { StaticQuery, graphql } from "gatsby"
import Img from "gatsby-image"
const Image = (props) => (
<StaticQuery
query={graphql`
query {
images: allFile {
edges {
node {
relativePath
name
childImageSharp {
fluid(maxWidth: 300) {
...GatsbyImageSharpFluid
}
}
}
}
}
}
`}
/*
サイズFIXしたい時は上記childImageSharp {...}の中を以下のように変更
sizes(maxWidth: 300) {
...GatsbyImageSharpSizes
}
*/
render={(data) => {
const image = data.images.edges.find(n => {
return n.node.relativePath.includes(props.filename);
});
if (!image) { return null; }
//const imageSizes = image.node.childImageSharp.sizes; ←サイズFIXしたい時
return (
/*<Img alt={props.alt} sizes={imageSizes} /> ←サイズFIXしたい時 */
<Img fluid={image.node.childImageSharp.fluid} alt={props.alt} />
);
}}
/>
)
export default Image
表示させる側では次のように画像ファイル名を指定する。画像はもちろんデフォルトのsrc/imagesフォルダ配下に置くだけ。
// index.js
・・・略・・・
<Image filename="gatsby-astronaut.png" alt="Gatsbyスペースマン" />
・・・略・・・
スタティックに読み込んで表示させる
しかしどうしてもsrc=""といった読み込み方をしたい場合がある。たとえばReact bootstrapでCard.imgのsrc属性。以下のように
<Card>
<Card.Body>
<Card.Img variant="top" src="" />
<Card.Title>タイトル</Card.Title>
<Card.Text>
本文本文本文本文本文本文本文本文本文本文本文本文
</Card.Text>
</Card.Body>
</Card>
こんな場合に<Card.Img variant="top" src="./images/gatsby-astronaut.png" />
とかやっても怒られる。ではどうするか?
まずインポートする
import gatsbyOjisanImg from './images/gatsby-astronaut.png'
でインポートする。そしてgatsbyOjisanImg
をsrcの引数に。
import React from "react"
import { Card } from 'react-bootstrap'
import gatsbyOjisanImg from './images/gatsby-astronaut.png' // ←ココ
<Card>
<Card.Body>
<Card.Img variant="top" src={gatsbyOjisanImg } />
<Card.Title>タイトル</Card.Title>
<Card.Text>
本文本文本文本文本文本文本文本文本文本文本文本文
</Card.Text>
</Card.Body>
</Card>
ステップがひとつ増えてめんどくさいかもしれないがそのかわり、画像の最適化をGatsbyがやってくれる。
以下はかなり大きな表画像をCard.imgに指定したがGatsbyが最適化して表示してくれたbootstrapカードの一例。
以上。
本の宣伝
Gatsbyバージョン5>>>>改訂2版
前編の『Gatsby5前編ー最新Gatsbyでつくるコーポレートサイト』と後編の『Gatsby5後編ー最新GatsbyとmicroCMSでつくるコーポレートサイト《サイト内検索機能付き》』を合わせ、次のようなデモサイトを構築します。
→ https://yah-space.work
静的サイトジェネレーターGatsby最新バージョン5の基本とFile System Route APIを使用して動的にページを生成する方法を解説。またバージョン5の新機能《Slicy API》《Script API》《Head API》を紹介、実装方法も。《Gatsby Functions》での問い合わせフォーム実装やGatsby Cloudへのアップロード方法も!
Gatsby5前編ー最新Gatsbyでつくるコーポレートサイト ~基礎の基礎から応用、新機能の導入まで(書籍2,980円)
最新Gatsby5とmicroCMSを組み合わせてのコーポレートサイト作成手順を解説。《サイト内検索機能》をGatsbyバージョン4からの新機能《Gatsby Functions》と《microCMSのqパラメータ》で実装。また、SEOコンポーネントをカスタマイズしてmicroCMS APIをツイッターカードに表示させるOGPタグ実装方法も解説。
Gatsby5後編ー最新GatsbyとmicroCMSでつくるコーポレートサイト《サイト内検索機能付き》(書籍 2,790円)