Thi's avatar
HomeAboutNotesBlogTopicsToolsReading
About|My sketches |Cooking |Cafe icon Support Thi
💌 [email protected]

Gatsby Images

Anh-Thi Dinh
GatsbySSGWeb Dev
Left aside
Because the post Gatsby descrete notes is too long, I write a separate post just for images in Gatsby.

Rule of thumb

  • Static images (icon, logo, favicon): just import and use img.
  • svg cannot be used with childImageSharp, just use <img> with its publicURL.
  • png, jpg can be used with <Img> and childImageSharp.
  • Data can be used: json or yaml, cannot use js for images.
  • List of images are get up to edges. After edges, there are a loop of nodes.
  • query components must placed in <StaticQuery />.
  • Different screen solution: use fixed.
  • Different screen size: use fluid.
  • Use http://localhost:8000/___graphql to check the query.
  • Use {condition && condition && output} instead of using if..else...
  • The relative path of images is compared with the path of data file where the urls are indicated.

Type of images to be processed

Read this post from CSS-Tricks to know which images should be processed, which ones should not.
  • No processing required: "static images", icons and logos, favicons 👉 We can import and use <img> to directly import them.
  • Process required: PNG, JPG files, gallery, ...

Single photo

Install stuffs following this doc

Insert directly,

Using data/query

So that we can have the lazing loading / resizing / blur-up (traced placeholder) effects.
Below technique is just for single photos.
👉 Most of tutorials like this or this don't talk about StaticQuery (Gatsby v2). I followed them but it didn't work, we have to use StaticQuery to make things work! 👉 The reason is that the (old) page query can only be added to page components (in my try, I add in Header.js component). StaticQuery can be used as a replacement of page query, it can be added to any component. (ref)
👉 There are 2 types:
  • fixed: has a set width and height and is for supporting different screen resolutions. It accepts width and height.
  • fluid: has a max-width and sometimes a max-height, and will create multiple images for supporting different screen sizes. It accepts maxWidth and maxHeight.
You need to use them with fragments like GatsbyImageSharpFixed_tracedSVG or GatsbyImageSharpFluid (more).

Using absolute path

If you want to query to an image in /src/images/example.png, you can use,

SVG files

gatsby-plugin-sharp / gatsby-image doesn't handle SVGs or GIFs. If you want to use your svg you, e.g. could import / use it like import yourSVG from './logo_large.svg'. (ref)

Change favicon

Put favicon.png in src/images and then change gatsby-config.js
You need to restart gastby to see the result!

Multiple images from data file/folder

Images' URLs stored in a JSON file

Suppose that we store some images in /src/images/ and we indicate them in a json file like this,
Images (github.svg, linkedin.svg, math2it.png) are stored in the same folder of your json file, that why we put ./ before them!
❓ There are both png and svg files in the list. We cannot use childImageSharp for svg files. How can we "loop" through each item and consider differently svg and png files?
💡 Read this tutorial to read data from a json file.
  1. Having a json file, in this example, it's /data/AccountItem.json (you can name it whatwever you want but its name is really important for using later!!!)
  1. Install
  1. Inside /gatsby-config.js, add following (direction in path is the direction to the folder containing your json file),
  1. Suppose that we wanna load images in a component /src/components/ListAccount.js. Put in it, (ref)
Explaination:
  • We have to put extension and publicURL inside icon because there are svg files!
  • For more intuition, look at http://localhost:8000/___graphql.
  • In edges, there are many nodes, each of them is relating to the item inside AccountItem.json. That's why the input data for <ListAccount /> must be data.allAccountItemsJson.edges.
  • For each account in accounts, we have to pass account.node before each attribute name, icon.
  • {condition && condition && output} is a trick for not using if...else.
👉 In the case you store images in a different folder, let's say /src/images/accounts/, you have to indicate it in /data/AccountItems.json:

Using YAML data file

Suppose our yaml file,
The same technique as in the case of json file. In this case, we need to install gatsby-transformer-yaml
In your gatsby-config.js

query as an input

In the previous step, query is considered inside the component file. What if you wanna query data and then pass it in a JSX components? (check index.js for an example)
There is a data file /data/MostProudOfItems.yaml.

Get all images from a specific folder

👉 This is also a way you use the name indicate in gatsby-config.js.
Suppose that you wanna show all images in /sketches/. (ref)
💢 Above method is only works with /sketches (folder locates at the root of site). It doesn't work with /src/images/sketches, for example. I don't know why!
👉 If you want to get all images from a folder (without using sourceInstanceName) you can use relativeDirectory in the query. Suppose that we have 2 folders with the same name sketches, one is in /content/sketches, one is in /src/images/sketches. The following code will load all images in these two folders!
💢 Make sure the name of your folder is unique if you don't want to load images from a wrong location.

References

  • A comprehensive guide to images in Gatsby by James Allardice.
  • Image Processing with gatsby-transformer-sharp.
  • Building A Custom, Accessible Image Lightbox In GatsbyJS
◆Rule of thumb◆Type of images to be processed◆Single photo○Insert directly,○Using data/query○Using absolute path○SVG files◆Change favicon◆Multiple images from data file/folder○Images' URLs stored in a JSON file○Using YAML data file◆query as an input◆Get all images from a specific folder◆References
About|My sketches |Cooking |Cafe icon Support Thi
💌 [email protected]
1npm install --save gatsby-image gatsby-plugin-sharp gatsby-transformer-sharp
1import avatar from "src/images/site/avatar.jpg"
2function Header() {
3  return <img src={logo} alt="Logo" />
4}
5export default Header
1npm install --save gatsby-image gatsby-transformer-sharp gatsby-plugin-sharp
1// gatsby-config.js
2module.exports = {
3  plugins: [
4    ...
5    'gatsby-plugin-sharp',
6    'gatsby-transformer-sharp',
7    {
8      resolve: 'gatsby-source-filesystem',
9      options: {
10        name: 'images',
11        path: path.join(__dirname, `src`, `images`),
12      },
13    },
14  ],
15}
1// src/components/Header.js
2import { StaticQuery, graphql } from 'gatsby';
3import Img from 'gatsby-image';
4
5const Header = ({ data }) => (
6  <header>
7    <Img fluid={data.myAvatar.childImageSharp.fluid} />
8  </header>
9)
10
11// src/images/avatar.png
12export default props => (
13  <StaticQuery
14    query={graphql`
15      query {
16        myAvatar: file(relativePath: { eq: "avatar.png" }) {
17          childImageSharp {
18            fluid(maxWidth: 150) {
19              ...GatsbyImageSharpFluid
20            }
21          }
22        }
23      }
24    `}
25    render={data => <Header data={data} {...props} />}
26  />
27)
1export const query = graphql`
2  query {
3    file(absolutePath: {
4      regex: "/\\\\/src\\\\/images\\\\/example\\\\.png/"
5    }) {
6      childImageSharp {
7        fixed(width: 800) {
8          ...GatsbyImageSharpFixed
9        }
10      }
11    }
12  }
13`
1{
2  resolve: `gatsby-plugin-manifest`,
3  options: {
4    // other stuffs
5    icon: `src/images/favicon.png`,
6  },
7},
1// File /data/AccountItem.json
2[
3  {
4    "name": "Github",
5    "icon": "./github.svg",
6  },
7  {
8    "name": "LinkedIn",
9    "icon": "./linkedin.svg",
10  },
11  {
12    "name": "Math2IT",
13    "icon": "./math2it.png",
14  }
15]
1npm install gatsby-transformer-json gatsby-source-filesystem --save
1`gatsby-transformer-json`,
2{
3  resolve: 'gatsby-source-filesystem',
4  options: {
5    name: 'data',
6    path: `${__dirname}/data/`,
7  },
8}
1import { StaticQuery, graphql } from 'gatsby';
2import Img from 'gatsby-image'
3
4const ListAccount = ( {accounts} ) => (
5  <div>
6    {accounts.map(account => (
7      <div className="item">
8        <div className="img">
9          {!account.node.icon.childImageSharp
10            && (account.node.icon.extension === 'svg')
11            && <img src={account.node.icon.publicURL} />
12            }
13          {account.node.icon.extension !== 'svg'
14            && <Img fixed={account.node.icon.childImageSharp.fixed} />
15            }
16        </div>
17      </div>
18    ))}
19  </div>
20)
21//
22export default props => (
23  <StaticQuery
24    query={graphql`
25      query AccountItemsQuery {
26        allAccountItemsJson{
27          edges{
28            node{
29              name
30              icon{
31                childImageSharp {
32                  fixed(width: 150, height: 150) {
33                    ...GatsbyImageSharpFixed_tracedSVG
34                  }
35                }
36                extension
37                publicURL
38              }
39            }
40          }
41        }
42      }
43    `}
44    render={data => <ListAccount accounts={data.allAccountItemsJson.edges} {...props} />}
45  />
46)
1[
2  {
3    "icon": "../src/images/accounts/github.svg",
4  }
5]
1// File /data/AccountItem.yaml
2
3- name: Github
4  icon: ./github.svg
5- name: LinkedIn
6  icon: ./linkedin.svg
7- name: Math2IT
8  icon: ./math2it.png
1npm install --save gatsby-transformer-yaml
1`gatsby-transformer-yaml`,
2{
3  resolve: `gatsby-source-filesystem`,
4  options: {
5    name: 'data',
6    path: `${__dirname}/data/`,
7  },
8},
1// in /src/pages/index.js
2
3import ShortcutListing from "../components/ShortcutListing"
4
5const indexPage = (props) => (
6  <ShortcutListing
7    shortcuts={props.data.allMostProudOfItemsYaml.edges}
8    nShortcutsPerRow='3' />
9)
10
11export default IndexPage
12
13export const pageQuery = graphql`
14  query IndexQuery {
15    allMostProudOfItemsYaml{
16      edges {
17        node {
18          title
19          img {
20            childImageSharp {
21              fixed(width: 100, height: 100) {
22                ...GatsbyImageSharpFixed_tracedSVG
23              }
24            }
25            extension
26            publicURL
27          }
28          url
29        }
30      }
31    },
32    anotherYaml{
33      ....
34    }
35  }
36`
1// in /src/components/ShortcutListing
2
3const ListShortcut = ({shortcuts, nShortcutsPerRow}) => (
4  // ...
5)
6
7export default ListShortcut
1// In /gatsby-config.js
2{
3  resolve: "gatsby-source-filesystem",
4  options: {
5    path: `${__dirname}/sketches/`,
6    name: "sketchFolder",
7  },
8},
1export const pageQuery = graphql`
2  query IndexQuery {
3    allFile(filter: {
4      extension: {regex: "/(jpg)|(jpeg)|(png)/"},
5      sourceInstanceName: {eq: "sketchFolder"}})
6    {
7      edges {
8        node {
9          childImageSharp {
10            fluid {
11              originalName
12            }
13          }
14          absolutePath
15        }
16      }
17    }
18  }
19`
1// In /gatsby-config.js
2{
3  resolve: "gatsby-source-filesystem",
4  options: {
5    path: `${__dirname}/content/`,
6    name: "content",
7  },
8},
9{
10  resolve: "gatsby-source-filesystem",
11  options: {
12    path: `${__dirname}/src/images`,
13    name: "images",
14  },
15},
1export const pageQuery = graphql`
2  query IndexQuery {
3    allFile(filter: {
4      extension: {regex: "/(jpg)|(jpeg)|(png)/"},
5      relativeDirectory: {eq: "sketches"}})
6    {
7      edges {
8        node {
9          childImageSharp {
10            fluid {
11              originalName
12            }
13          }
14          absolutePath
15        }
16      }
17    }
18  }
19`
20