MDX and inline images in Gatsby

X @urre

MDX and inline images in Gatsby

1. Plain old images, no processing

This is the simplest option. When you do this, images won’t be processed in any way by Gatsby.

  1. Place images in static/images
  2. Reference like this ![A blue bicycle](/static/images/bicycle.jpg)

2. Images processed by Sharp and gatsby-plugin-image

This is easy to miss in the Docs. If you do this, the images will be processed by sharp and appear as if you placed them in a gatsby-plugin-image component. So you benefit from allt he goodies in, responsive images/placeholders/modern image formats and more.

  1. Place images in src/images
  2. Install npm install gatsby-plugin-image gatsby-plugin-sharp gatsby-source-filesystem gatsby-transformer-sharp
  3. Configure gatsby-config.js or if you use Gatsby 5+ and ESM you edit gatsby-config.mjs
plugins: [
  "gatsby-plugin-image",
  {
    resolve: `gatsby-plugin-mdx`,
    options: {
      gatsbyRemarkPlugins: [
        {
          resolve: `gatsby-remark-images`,
          options: {
            maxWidth: 1200,
          },
        },
      ],
    },
  },
  "gatsby-plugin-sharp",
  "gatsby-transformer-sharp",
  {
    resolve: "gatsby-source-filesystem",
    options: {
      name: "images",
      path: "./src/images/",
    },
    __key: "images",
  }
]
  1. Reference like this ![A blue bicycle](../images/bicycle.jpg)

Read more about images in MDX

3. Use a separate React component that uses Gatsby Image

The two image components <GatsbyImage /> and <StaticImage /> is meant to be used in JSX, not in MDX. You can however, if you want; create a separate Image component.

import React from "react";
import { graphql, useStaticQuery } from "gatsby";
import { GatsbyImage, getImage } from "gatsby-plugin-image";

export const Image = ({ src, alt }) => {
  const data = useStaticQuery(graphql`
    query {
      allFile {
        nodes {
          relativePath
          childImageSharp {
            gatsbyImageData(
              placeholder: BLURRED
              formats: [AUTO, WEBP, AVIF]
            )
          }
        }
      }
    }
  `);

  const imageNode = data.allFile.nodes.find(
    (node) => node.relativePath === src
  );

  if (!imageNode || !imageNode.childImageSharp) {
    return <div>Image not found</div>;
  }

  const image = getImage(imageNode.childImageSharp);

  return (
    <div>
      <GatsbyImage image={image} alt={alt} />
    </div>
  );
};

And then use like this:

import { Image } from "components/Image"
<Image src="cycle.jpg" alt="An alt text"/>

Conclusion

  • Option 1) – Don’t process my images. I’ll do it myself
  • Option 2) – I want to let Gatsby process my images and benefit from the goodies in gatsby-plugin-images. Will peform best regarding SEO, Web Core Vitals etc.
  • Option 3) – Just to show an alternative way using a custom React component. But i recommend using 2).

Read more about gatsby-plugin-image