↩ī¸Ž

A Complete Guide to Importing Images in GatsbyJS

How to import images in your GatsbyJS project.

Using Gatsby Image

Installing plugins

For this method, you will have to import every image one-by-one, however, your images will be processed and optimized for the best performance. Usually, this is the method that you'd want to use.

First, install gatsby-image, gatsby-transformer-sharp and gatsby-plugin-sharp using the command:

yarn add gatsby-image gatsby-transformer-sharp gatsby-plugin-sharp

And add them to the plugins array in gatsby-config.js:

module.exports = {
  plugins: [
    `gatsby-transformer-sharp`,
    `gatsby-plugin-sharp`,
    ... // your others plugins
  ]
}

Also, don't forget to add your images to your source plugin. For instance, if you are using gatsby-source-filesystem, you can configure it in gatsby-config.js like so:

module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/images`,
      },
    },
    `gatsby-transformer-sharp`,
    `gatsby-plugin-sharp`,
    ... // your others plugins
  ]
}

Querying images in pages and components

In order to query images using GraphQL in your pages and your components, you will have to import gatsby-image at the top of the file. In this example, I am going to assume that you are using a StaticQuery for your component or your page. If that's the case, I highlighy recommend using the StaticQuery snippet for VS Code.

import React from "react"
import Img from "gatsby-image"

then query your image using GraphQL

const myQuery = graphql`
	query {
		nameOfImage: file(relativePath: { eq: "relativePathToYourImage.png" }) {
			childImageSharp {
				fixed(height: 200) {
					...GatsbyImageSharpFixed
				}
			}
		}
	}
`

A couple of notes here:

  1. nameOfImage could be anything. You will use it later in your JSX.
  2. relativePathToYourImage.png is the relative path to your with the images file defined above---in gatsby-config.js---as a base. You can of course change relativePath to your liking.
  3. fixed is for images with a fixed width and height. It generates images for different screen resolutions. You can use the height and width to determine the dimensions of your image. However, if you want to make your image fluid or responsive, that is, with multiple sizes based on the screen size, you would have to use fluid instead of fixed. And instead of a height and width, you have to define either a maxWidth or maxHeight (or both).
const myQuery = graphql`
	query {
		nameOfImage: file(relativePath: { eq: "relativePathToYourImage.png" }) {
			childImageSharp {
				fluid(maxHeight: 200) {
					...GatsbyImageSharpFluid
				}
			}
		}
	}
`

Finally, you can use your image in your component by using Img and passing it the image as a property. For instance, for fluid images you would use <Img fluid={data.nameOfImage.childImageSharp.fluid} /> and for fixed images, you would use <Img fixed={data.nameOfImage.childImageSharp.fixed} />.

A component with images imported using GraphQL would look like this:

import React from "react"
import { StaticQuery, graphql } from "gatsby"
import Img from "gatsby-image"

const OurComponent = ({ data }) => (
	<main>
		<p>A fluid image: </p>
		<Img fluid={data.nameOfFluidImage.childImageSharp.fluid} />

		<p>A fixed image: </p>
		<Img fixed={data.nameOfFixedImage.childImageSharp.fixed} />
	</main>
)

const ourQuery = graphql`
	query {
		nameOfFluidImage: file(
			relativePath: { eq: "relativePathToYourImage.png" }
		) {
			childImageSharp {
				fluid(maxHeight: 200) {
					...GatsbyImageSharpFluid
				}
			}
		}
		nameOfFixedImage: file(
			relativePath: { eq: "relativePathToYourImage.png" }
		) {
			childImageSharp {
				fixed(height: 200) {
					...GatsbyImageSharpFixed
				}
			}
		}
	}
`

export default () => (
	<StaticQuery query={ourQuery} render={data => <OurComponent data={data} />} />
)

Using Webpack Import

With Webpack, you can import a file directly in your component or page without all of the configuration of gatsby-image. This is especially useful with a large number of images, for quick prototyping, or if your images are already optimized and minified.

Note that importing images that are less than 10000 bytes returns a data URI instead of a path. This applies to the following file extensions: svg, jpg, jpeg, png, gif, mp4, webm, wav, mp3, m4a, aac, and oga.

Using Import

First, you need to import your image as you usually would for JavaScript files.

import React from "react"
import myImage from "./pathToTheImage.png"

Afterwards, you can treat it as a normal path:

const MyComponent = () => <img src={myImage} alt="A bunch of 0s and 1s" />

Note that you can achieve the same thing in your CSS files, without having to import it:

.decorativeImage {
	background-image: url(./pathToTheImage.png);
}

This way, you can add your background images to your Gatsby project---although using background images is not recommended from an accessibility point of view.

Inline Require

As the number of images grows, importing every single image can become tedious. Hopefully, an easier solution is using an inline require like so:

const AnotherComponent = () => <img src={require("./pathToTheImage.png")} />

Require All Images

Similar to the import method above, you can require all images using this function:

const images = require.context("../images", true)
const imagePath = name => images(name, true)

Specify where the images are stored and then use it like so

const AndAnotherComponent = () => (
	<img src={imagePath("./pathToTheImage.png")} />
)

Using The Static Folder

Finally, if you don't have time for all of this and you don't really worry about optimization 🙄, you can add a static folder to the root of your project, add any images you want there, and then easily reference images like so:

const Yup = () => <img src="pathToTheImage.png" />

Note that the static folder is considered the base for your image's path.

Conclusion

  • Optimize images: gatsby-image FTW;
  • Import in CSS: relative image path, Webpack will handle it;
  • Import many images quickly: inline require, Webpack will handle it;
  • 🙄: use the static folder.

Further Reading