Skip to main content

Adding Images, Fonts, and Files

With Webpack you can import a file right in a JavaScript module. This tells Webpack to include that file in the bundle. Unlike CSS imports, importing a file gives you a string value. This value is the final path you can reference in your code, e.g. as the src attribute of an image or the href of a link to a PDF.

To reduce the number of requests to the server, importing images that are less than 10,000 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.

Here is an example:

import React from "react"
import logo from "./logo.png" // Tell Webpack this JS file uses this image

console.log(logo) // /logo.84287d09.png

function Header() {
  // Import result is the URL of your image
  return <img src={logo} alt="Logo" />

export default Header

This ensures that when the project is built, Webpack will correctly move the images into the public folder, and provide us with correct paths.

This works in CSS too:

.Logo {
  background-image: url(./logo.png);

Webpack finds all relative module references in CSS (they start with ./) and replaces them with the final paths from the compiled bundle. If you make a typo or accidentally delete an important file, you will see a compilation error, just like when you import a non-existent JavaScript module. The final filenames in the compiled bundle are generated by Webpack from content hashes. If the file content changes in the future, Webpack will give it a different name in production so you don’t need to worry about long-term caching of assets.

If you’re using SCSS the imports are relative to the entry SCSS file.

Please be advised that this is also a custom feature of Webpack.

Two alternative ways of handling static assets are described in the next sections.

Query for File in GraphQL queries using gatsby-source-filesystem

You can query the publicURL field of File nodes found in your data layer to trigger copying those files to the public directory and get URLs to them.


  • Copy all .pdf files you have in your data layer to your build directory and return URLs to them:
  allFile(filter: { extension: { eq: "pdf" } }) {
    edges {
      node {
  • Copy post attachments defined in your Markdown files:

    Link to your attachments in the markdown front matter:

title: "Title of article"
  - "./"
  - "./presentation.pdf"

Hi, this is a great article.

In the article template component file, you can query for the attachments:

query($slug: String!) {
  markdownRemark(fields: { slug: { eq: $slug } }) {
    frontmatter {
      attachments {

Using the static Folder

You can also add other assets to a static folder at the root of your project. Check the static folder page to learn more.

Note that we normally encourage you to import assets in JavaScript files instead. This mechanism provides a number of benefits:

  • Scripts and stylesheets get minified and bundled together to avoid extra network requests.
  • Missing files cause compilation errors instead of 404 errors for your users.
  • Result filenames include content hashes so you don’t need to worry about browsers caching their old versions.

However, there is an escape hatch that you can use to add an asset outside of the module system.

If you put a file into the static folder, it will not be processed by Webpack. Instead, it will be copied into the public folder untouched. E.g. if you add a file named sun.jpg to the static folder, it’ll be copied to public/sun.jpg. To reference assets in the static folder, you’ll need to import a helper function from gatsby named withPrefix. You will need to make sure you set pathPrefix in your gatsby-config.js for this to work.

import { withPrefix } from 'gatsby'

render() {
  // Note: this is an escape hatch and should be used sparingly!
  // Normally we recommend using `import` for getting asset URLs
  // as described in “Adding Images and Fonts” above this section.
  return <img src={withPrefix('/img/logo.png')} alt="Logo" />;

Keep in mind the downsides of this approach:

  • None of the files in static folder get post-processed or minified.
  • Missing files will not be called at compilation time, and will cause 404 errors for your users.
  • Result filenames won’t include content hashes so you’ll need to add query arguments or rename them every time they change.

When to Use the static Folder

Normally we recommend importing stylesheets, images, and fonts from JavaScript. The static folder is useful as a workaround for a number of less common cases:

  • You need a file with a specific name in the build output, such as manifest.webmanifest.
  • You have thousands of images and need to dynamically reference their paths.
  • You want to include a small script like pace.js outside of the bundled code.
  • You are using a library that is incompatible with Webpack and need to include it as a <script> tag.

edit this page on GitHub