Day157 — get images from json in Gatsby
Here records the method I used to import images from a json file in Gatsby.js v5.
By the nature of the Gatsby.js framework, anything dynamic relies on graphql query. Therefore, graphal query plus GatsbyImage
are used. Graphql query is used to query the data from the json file, while the GatsbyImage
is used to interpret the queried image object for display.
Versions used:
"gatsby": "^5.3.3",
"gatsby-plugin-image": "^3.3.2",
"gatsby-plugin-sharp": "^5.3.2",
"gatsby-source-filesystem": "^5.3.1",
"gatsby-transformer-json": "^5.3.0",
"gatsby-transformer-sharp": "^5.3.1",
folder structure:
- src/pages/index.html
- src/images/icon.png
- src/data/source.json
-src
┕-pages
┕-index.html
┕-images
┕-icon.png
┕-data
┕-source.json
In gatsby-config.ts
,
const config: GatsbyConfig = {
// ...
plugins: [
`gatsby-plugin-image`,
`gatsby-plugin-sharp`,
`gatsby-transformer-sharp`, // Needed for dynamic images
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: path.join(__dirname, `src`, `images`),
},
},
`gatsby-transformer-json`,
{
resolve: `gatsby-source-filesystem`,
options: {
path: path.join(__dirname, `src`, `data`),
},
},
]
}
In src/data/source.json
,
[
{
"name": "data1",
"image": "../images/icon.png"
},
{
"name": "data2",
"image": "../images/icon.png"
}
]
Image paths must be written in relative. Otherwise, the gatsby plugin would not recognize them by default.
In src/pages/index.html
,
const dataQuery = graphql`
query Projects {
allSourceJson {
nodes {
name
image {
childImageSharp {
gatsbyImageData(
placeholder: BLURRED
formats: [AUTO, WEBP, AVIF]
layout: FULL_WIDTH
aspectRatio: 2
transformOptions: {cropFocus: ATTENTION}
)
}
}
}
}
}
`
If the json file is written correctly, the image
would be recognized as a File
object in graphql. Then, it will have the childImageSharp
property to select for query.
It would be best to verify the graphql query in “http://localhost:8000/___graphql”.
To use the query, you can write
import { GatsbyImage, getImage, ImageDataLike } from "gatsby-plugin-image"
const Image = ({ image, name }: ImageProps) =>
<GatsbyImage image={getImage(image)} alt={name} />
const IndexPage = () => {
const sourceData = useStaticQuery(dataQuery)
const sources = sourceData.allProjectsJson.nodes
return (
<main>
<Image image={sources[0].image} name={sources[0].name} />
</main>
)
}
Bonus:
querying the same image in a different format using graphql alias
const dataQuery = graphql`
query Projects {
allSourceJson {
nodes {
name
image {
childImageSharp {
gatsbyImageData(
placeholder: BLURRED
formats: [AUTO, WEBP, AVIF]
layout: FULL_WIDTH
aspectRatio: 2
transformOptions: {cropFocus: ATTENTION}
)
}
}
fullImage: image {
childImageSharp {
gatsbyImageData(
placeholder: BLURRED
formats: [AUTO, WEBP, AVIF]
layout: FULL_WIDTH
)
}
}
}
}
}
`
References: