Gatsby Image Plugin — Optimized Images with gatsby-plugin-image
In this tutorial, you will learn about Gatsby Image Plugin. We cover key concepts, practical examples, and best practices to help you master this topic.
Learn gatsby-plugin-image for optimized images with Lazy Loading, responsive sizes, AVIF/WebP formats, and blurred placeholders in Gatsby.
In this lesson, you'll understand the Gatsby Image plugin components: StaticImage, GatsbyImage, and how they optimize images automatically.
What You'll Learn
How to use StaticImage for simple images, GatsbyImage for dynamic images from Graphql, configure image formats, and understand image fragment patterns.
Why It Matters
Images are the largest performance bottleneck on most websites. Gatsby's image plugin automatically optimizes images, reducing load times by 40-60%.
flowchart LR
A[Source Image] --> B[Sharp Processing]
B --> C[Resize to Multiple Sizes]
B --> D[Convert to AVIF/WebP]
B --> E[Generate Blurred Placeholder]
C --> F[Responsive srcSet]
D --> G[Modern Format]
E --> H[Lazy Loading Placeholder]
style B fill:#639,color:#fff
Static Image
For images known at build time:
import { StaticImage } from 'gatsby-plugin-image';
import React from 'react';
function Logo() {
return (
<StaticImage
src="../images/logo.png"
alt="Company Logo"
width={200}
height={50}
placeholder="blurred"
layout="fixed"
/>
);
}
Output: The image is optimized at build time: resized to 200x50, converted to WebP/AVIF, with a blurred placeholder. The component renders a responsive <picture> element.
GatsbyImage with GraphQL
For dynamic images sourced from filesystem:
query {
file(relativePath: { eq: "hero.jpg" }) {
childImageSharp {
gatsbyImageData(
width: 1200
aspectRatio: 1.5
placeholder: BLURRED
formats: [AVIF, WEBP, AUTO]
layout: constrained
)
}
}
}
import { graphql, useStaticQuery } from 'gatsby';
import { GatsbyImage, getImage } from 'gatsby-plugin-image';
import React from 'react';
function Hero() {
const data = useStaticQuery(graphql`
query {
file(relativePath: { eq: "hero.jpg" }) {
childImageSharp {
gatsbyImageData(
width: 1200
placeholder: BLURRED
formats: [AVIF, WEBP, AUTO]
)
}
}
}
`);
const image = getImage(data.file);
return <GatsbyImage image={image} alt="Hero image" />;
}
Output: The image is fetched via GraphQL, optimized with the specified options, and rendered with lazy loading and modern formats.
Image Layouts
Choose the right layout for your design:
// Fixed — exact pixel dimensions, no stretching
<StaticImage src="icon.png" width={50} height={50} layout="fixed" />
// Constrained — responsive within bounds, maintains aspect ratio
<StaticImage src="photo.jpg" width={800} layout="constrained" />
// Full width — always fills container width, height scales
<StaticImage src="banner.jpg" layout="fullWidth" />
Output: fixed keeps exact dimensions. constrained grows up to the specified width. fullWidth always fills the container with responsive sizes.
Placeholder Options
Control the loading experience:
// Blurred — show a 20x20 blurred version while loading (default)
<StaticImage src="large.jpg" placeholder="blurred" />
// Dominant color — show solid background color
<StaticImage src="large.jpg" placeholder="dominantColor" />
// Traced SVG — show a low-fidelity SVG outline
<StaticImage src="large.jpg" placeholder="tracedSVG" />
// None — show nothing while loading
<StaticImage src="large.jpg" placeholder="none" />
Output: The placeholder appears instantly while the full image loads. blurred provides the best visual result. none is fastest for unimportant images.
Image Fragment
Create reusable GraphQL fragments:
// gatsby-fragments.js
import { graphql } from 'gatsby';
export const HeroImage = graphql`
fragment HeroImage on File {
childImageSharp {
gatsbyImageData(
width: 1200
placeholder: BLURRED
formats: [AVIF, WEBP, AUTO]
)
}
}
`
import { graphql, useStaticQuery } from 'gatsby';
function Hero() {
const data = useStaticQuery(graphql`
query {
file(relativePath: { eq: "hero.jpg" }) {
...HeroImage
}
}
`);
}
Output: The fragment defines the image query once and can be reused across components, ensuring consistent image configuration.
Common Mistakes
- Using
StaticImagewith dynamicsrc:StaticImagerequires a static string path. Dynamic paths likesrc={imagePath}won't work. UseGatsbyImagewith GraphQL instead. - Not querying
childImageSharp: ThechildImageSharpfield only exists if images are processed. Ensuregatsby-plugin-sharpandgatsby-transformer-sharpare configured. - Forgetting
getImage()helper: ThegetImage()function safely extracts thegatsbyImageDataobject. Accessingdata.file.childImageSharp.gatsbyImageDatadirectly may error. - Using
layout="fixed"for responsive images: Fixed layout doesn't resize in responsive layouts. UseconstrainedorfullWidthfor responsive designs. - Over-optimizing unimportant images: Not every image needs WebP/AVIF. Apply full optimization to hero and content images, but simple images can use basic formats.
Practice Questions
What is the difference between
StaticImageandGatsbyImage? Answer:StaticImageis for images known at build time with a static path.GatsbyImageis for dynamic images queried via GraphQL.What image formats does gatsby-plugin-image generate? Answer: AVIF, WebP, and fallback PNG/JPEG. The browser loads the best supported format.
What does
layout="fullWidth"do? Answer: The image always fills its container width and generates many responsive sizes from 100vw down to very small.How does blurred placeholder work? Answer: A 20px-wide version of the image is generated, blurred, and base64-encoded as a CSS background. It's replaced by the full image once loaded.
Challenge
Create a responsive image grid with 9 images using GatsbyImage. Each image should use layout="constrained" with different aspect ratios (portrait, landscape, square). Use a GraphQL fragment for the image query.
Mini Project
Build a product gallery page with a hero image, thumbnail strip, and zoomable main image. Use GatsbyImage for the main image and StaticImage for thumbnails. Implement click-to-select thumbnails.
FAQ
What's Next
Learn about Gatsby GraphQL Data Layer to understand how Gatsby collects and exposes data through GraphQL.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro