4

This is the code for a single image in any other Javascript framework in existence:

<img src="images/someFile.png" />

... possibly with some styling.

This is the code for a single image in Gatsby (basically copied from the Gatsby Image documentation page, https://www.gatsbyjs.org/docs/gatsby-image/ ... and this is just a simple example):

import { useStaticQuery, graphql } from "gatsby"
import Img from "gatsby-image"
export default function Image() {
  const data = useStaticQuery(graphql`
    query {
      file(relativePath: { eq: "images/someFile.png" }) {
        childImageSharp {
          fixed {
            ...GatsbyImageSharpFixed
          }
        }
      }
    }
  `)
  return (
      <Img fixed={data.file.childImageSharp.fixed} />
  )
}

Holy hell, I'm supposed to write all that code (ok, I don't have to repeat the imports, but still) for every image in my site?!?

That can't be right, so clearly I'm not understanding something. Can someone please clarify what I'm not getting about Gatsby?

If it truly takes that much code to just to add one image to a site, Gatsby must be the slowest framework ever to develop in (but from it's popularity I can't believe that's true). Or do most Gatsby sites just use very few images?

Ferran Buireu
  • 28,630
  • 6
  • 39
  • 67
machineghost
  • 33,529
  • 30
  • 159
  • 234
  • 3
    At a basic level (without transformations, dynamic sizes, etc) there are other ways to work with [images](https://www.gatsbyjs.org/docs/images-and-files/) including importing images into your code and/or using the static folder. – Alexander Staroselsky Jun 24 '20 at 19:32
  • 2
    You can put an image in the static catalogue and it will be moved to public, then your `` should work the same way. :) – Deykun Jun 24 '20 at 20:39
  • 1
    It's not required to move an image to `/static` folder to use it in any component. You can import it like a React component like `import Image from '../../any/path'` and then `` – Ferran Buireu Jun 25 '20 at 06:49

3 Answers3

1

At the very start of the page which you mention there is a bit of explanation

gatsby-image is a React component designed to work seamlessly with Gatsby’s native image processing capabilities powered by GraphQL and gatsby-plugin-sharp to easily and completely optimize image loading for your sites.

gatsby-plugin-sharp can compress jpeg/png images

Holy hell, I'm supposed to write all that code (ok, I don't have to repeat the imports, but still) for every image in my site?!?

I think you can extract some things as params like eq: "images/someFile.png" and make it reusable

Example

import { useStaticQuery, graphql } from "gatsby"
import Img from "gatsby-image"
export default function Image({source}) {
  const { file: {childImageSharp: {fixed} } } = graphql(`
    query($source: String!) {
      file(relativePath: { eq: $source }) {
        childImageSharp {
          fixed {
            ...GatsbyImageSharpFixed
          }
        }
      }
    }
  `, {source})
  return <Img fixed={fixed} />
}
Józef Podlecki
  • 10,453
  • 5
  • 24
  • 50
  • 1
    @machineghost with childImageSharp you can crop and resize an image, and gatsby have to know the dimensions to prepare those images while building. I'm not sure if it would work in dynamic components, and I'm not sure if the solution from that comment would work without useStaticQuery. – Deykun Jun 24 '20 at 20:37
  • Agree with @Deykun . In addition, when you retrieve your data and images from your CMS/data system you can set the GraphQL fragment and use all data object using directly `` component, you can avoid this implementation which I'm not sure if it will work dynamically as @Deykun explained. – Ferran Buireu Jun 24 '20 at 20:44
1

It's a nice topic to discuss and share. It's always up to you to use a <img> tag (importing assets directly in the component) or <Img> React's Component from Gatsby, adding and extending all support it has. From Gatsby Image documentation:

gatsby-image is a React component specially designed to work seamlessly with Gatsby’s GraphQL queries. It combines Gatsby’s native image processing capabilities with advanced image loading techniques to easily and completely optimize image loading for your sites. gatsby-image uses gatsby-plugin-sharp to power its image transformations.

Note: gatsby-image is not a drop-in replacement for <img />. It’s optimized for fixed width/height images and images that stretch the full-width of a container. Some ways you can use <img /> won’t work with gatsby-image.

So, without going into detail of all the benefits of using <Img> from Gatsby (compression, lazy loading, fluid sizes, etc), it's not that hard to implement for every single image if you take into account a few details.

Gatsby is a CMS/data-sourced based framework so, by default, all data comes from a CMS or somewhere outsourced, meaning that it has to be queried via GraphQL. In those queries, ideally, you'll prepare your data, images included. That will avoid you to use the staticQuery you showed. For example, retrieving all images once you've set up your filesystem should look like:

{
  allImageSharp {
    edges {
      node {
        fluid(maxWidth: 800) {
          ...GatsbyImageSharpFluid
        }
      }
    }
  }
}

Note: this is an example query, the idea is to fetch and gather all data needed from an image to pass it to <Img> component

Then, in your component you simply need to:

//...other imports
import Img from "gatsby-image"

const yourComponent= ({ data }) => {

  return <Layout>
    {data.edges.map(({ node })=> <Img fluid={node.childImageSharp.fluid} />)}
  </Layout>;
};

Gatsby's example from using <Img> maybe it's not the most accurate use-case to do it because it involves a staticQuery, another way of importing data that is not as usual as it seems. You can easily avoid it by using a standard GraphQL query, saving you a lot of lines of code.

What I'm trying to say is that if you set your data properly, using Gatsby's image it's almost like using the common HTML <img> tag.

The sample code you showed (from Gatsby's documentation) will always show the astronaut image, but of course, it's completely up to you to use a single <Img> component and remove the <Image> one or re-use it as you wish.

Ferran Buireu
  • 28,630
  • 6
  • 39
  • 67
1

See Importing Assets Directly Into Files and Using the Static Folder

import React from "react"
import importedImage from "../images/gatsby-icon.png"

const IndexPage = () => (
  <>
    <img src={importedImage} alt="Description of my imported image" />
    <img
      src="staticfolderimage.jpeg"
      alt="Description of my image in the ./static folder"
    />
  </>
)

export default IndexPage
ksav
  • 20,015
  • 6
  • 46
  • 66
  • 1
    I don't think it's a fair comparison between `gatsby-image` and your html `` example. So I thought I'd throw this answer into the mix, which is basically just recycled from here https://stackoverflow.com/a/57260882/5385381 – ksav Jun 25 '20 at 11:16