Skip to content

Gatsby Static Assets and Images — File Handling in Gatsby

DodaTech Updated 2026-06-28 4 min read

Learn how to handle static assets, images, fonts, and other files in Gatsby projects for optimal performance and build efficiency.

In this lesson, you'll understand how Gatsby processes files from the static/ directory and the src/ directory, and when to use each approach.

What You'll Learn

How to serve static files from the static/ directory, import assets from src/, optimize images, and handle fonts and PDFs.

Why It Matters

Proper asset handling affects both development workflow and production performance. Static files should be cached, optimized, and served efficiently.

flowchart LR
    A[Assets] --> B[static/ folder]
    A --> C[src/ imports]
    B --> D[Served as-is]
    B --> E[Known URL]
    C --> F[Webpack Processed]
    C --> G[Hash Fingerprinted]
    C --> H[Optimized]
    style A fill:#639,color:#fff
    style B fill:#4a148c,color:#fff

The static/ Folder

Files in static/ are copied to the build output as-is:

static/
├── favicon.ico
├── robots.txt
├── CNAME
├── fonts/
│   └── custom-font.woff2
└── downloads/
    └── guide.pdf

Reference them with absolute paths:

import React from 'react';

function Favicon() {
  return <link rel="icon" href="/favicon.ico" />;
}

function DownloadLink() {
  return <a href="/downloads/guide.pdf">Download Guide</a>;
}

Output: Files in static/ are served at the root URL. /favicon.ico becomes /favicon.ico in the built site.

Importing Assets from src/

Assets imported from src/ are processed by webpack:

import React from 'react';
import logo from '../images/logo.svg';
import heroImage from '../images/hero.jpg';

function Header() {
  return (
    <header>
      <img src={logo} alt="Logo" />
      <img src={heroImage} alt="Hero" />
    </header>
  );
}

Output: Webpack processes imported assets: SVGs may be inlined, images are optimized, and filenames get content hashes for cache busting.

Image Optimization

Use gatsby-plugin-image for optimized images:

npm install gatsby-plugin-image gatsby-plugin-sharp gatsby-transformer-sharp gatsby-source-filesystem
import { graphql } from 'gatsby';
import { GatsbyImage, getImage } from 'gatsby-plugin-image';
import React from 'react';

function Hero({ data }) {
  const image = getImage(data.file.childImageSharp.gatsbyImageData);

  return (
    <GatsbyImage
      image={image}
      alt="Hero background"
      loading="lazy"
    />
  );
}

export const query = graphql`
  query {
    file(relativePath: { eq: "hero.jpg" }) {
      childImageSharp {
        gatsbyImageData(
          width: 1200
          placeholder: BLURRED
          formats: [AVIF, WEBP, AUTO]
        )
      }
    }
  }
`;

Output: The image is automatically optimized: resized to 1200px, converted to AVIF/WebP, with a blurred placeholder. Only the optimal format is loaded.

Font Handling

Self-host fonts for performance:

static/fonts/
├── inter-v12-latin-regular.woff2
└── inter-v12-latin-700.woff2
/* src/styles/fonts.css */
@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter-v12-latin-regular.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
}

@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter-v12-latin-700.woff2') format('woff2');
  font-weight: 700;
  font-display: swap;
}

Output: Fonts are served from your own domain, avoiding third-party DNS lookups. font-display: swap ensures text remains visible during font loading.

PDFs and Other Files

Handle non-image files in GraphQL:

export const query = graphql`
  query {
    allFile(filter: { extension: { eq: "pdf" } }) {
      edges {
        node {
          publicURL
          name
          size
        }
      }
    }
  }
`
function DownloadList({ data }) {
  return (
    <ul>
      {data.allFile.edges.map(({ node }) => (
        <li key={node.publicURL}>
          <a href={node.publicURL}>{node.name}</a>
          <span>({(node.size / 1024).toFixed(0)} KB)</span>
        </li>
      ))}
    </ul>
  );
}

Output: All PDF files in sourced directories are listed with download links and file sizes.

Common Mistakes

  1. Putting files in static/ that should be processed: If an asset needs optimization or hashing, import it from src/ instead of putting it in static/.
  2. Using absolute paths incorrectly in CSS: CSS background images using url() from CSS Modules need different resolution. Use webpack's ~ prefix or import in JS.
  3. Not using gatsby-plugin-image for images: Without it, images are unoptimized: no Lazy Loading, no responsive sizes, no modern formats.
  4. Putting too many files in static/: Every file in static/ increases build time. Only put files here that shouldn't be processed.
  5. Linking to non-existent static files: Reference files in static/ with leading slash: /fonts/font.woff2. No relative paths.

Practice Questions

  1. What is the difference between files in static/ and imported from src/? Answer: static/ files are copied as-is. src/ imports are processed by webpack (optimized, hashed, inlined).

  2. How do you reference a file in static/? Answer: Use an absolute path: src="/filename.pdf". The file is served at the root URL.

  3. What does gatsby-plugin-image provide? Answer: Optimized images with lazy loading, responsive sizes, modern formats (AVIF, WebP), and blurred placeholders.

  4. Why use font-display: swap? Answer: It displays text immediately with a fallback font while the custom font loads, preventing invisible text (FOIT).

Challenge

Build a hero section with a background image using gatsby-plugin-image. Add a custom font using font-display: swap. Include a downloadable PDF brochure. Verify all assets load correctly in production build.

Mini Project

Create a gallery page with 10+ optimized images using gatsby-plugin-image. Display them in a responsive grid with lazy loading and AVIF/WebP format support.

FAQ

How do I measure image optimization impact?

: Use Lighthouse in Chrome DevToolsk "DevTools" >}}. Check the "Properly size images" and "Serve images in next-gen formats" audits.

Can I use SVGs in Gatsby?

: Yes. Import SVGs as React components with gatsby-plugin-react-svg or as file URLs with webpack's asset modules.

What file formats does `gatsby-plugin-image` output?

: It generates WebP and AVIF by default, with JPEG/PNG fallback. The browser loads the best supported format.

How do I add a favicon?

: Place favicon.ico in static/ or configure it in gatsby-plugin-manifest options.

What's Next

Learn about Gatsby Image Plugin for deep coverage of gatsby-plugin-image, fluid and fixed images, and advanced image techniques.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro