18

Looking at the Gatsby docs, they suggest that you can reference background images like you would anywhere else:

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

What they don't cover is where these images should live. I've tried placing the image directory in the src folder, in the layout folder, and in the root folder, but I keep getting the error:

Loader /Users/username/Sites/my-app/node_modules/url/url.js?{"limit":10000,"name":"static/[name].[hash:8].[ext]"} didn't return a function
 @ ./~/css-loader!./~/postcss-loader!./src/layouts/index.css 6:400-435

What's the proper way to reference a background image using Gatsby?

Current directory structure:

my-app
- src
-- images 
--- image.png
-- layouts
--- index.css
Aaron Benjamin
  • 1,291
  • 3
  • 18
  • 27
  • If you reference the image by `./image.png` in a CSS file in a folder called `src`, then the image should be in the same folder, i.e `src/image.png`. – Tholle Aug 09 '18 at 23:15

3 Answers3

34

Generally I keep component-specific images alongside their JSX and CSS files and general/global images in an images folder, so I might have a structure like this:

.
├── components
│   ├── button.jsx
│   ├── button.module.scss
│   └── button_icon.png
└── images
    └── logo.png

To reference button_icon.png from button.module.css I would do this:

background-image: url("./button_icon.png");

And to reference logo.png from button.module.css I would do this:

background-image: url("../images/logo.png");

Update: Lately I've been using Emotion with my Gatsby projects, which requires a slightly different approach. This would work with StyledComponents or Glamor as well:

import background from "images/background.png"
import { css } from "@emotion/core"

// Object styles:
<div css={{ backgroundImage: `url(${background})` }} />

// Tagged template literal styles:
const backgroundStyles = css`
  background-image: url(${background});
`
<div css={backgroundStyles} />

coreyward
  • 77,547
  • 20
  • 137
  • 166
  • Perfect, that works with Styled components! i put my images in the static folder under the root directory. – Petra Feb 14 '20 at 19:40
  • Thank you, it's work for styled-components. You're saved a lot of my time. – Thuan Nguyen Apr 14 '20 at 04:42
  • This is not working for me when using an svg, I'm using gatsby-plugin-react-svg to load svgs – jean182 Oct 12 '20 at 03:34
  • @jean182 You're using a plugin that alters the way this works, so of course it's not working the same. You wouldn't use a Toyota instruction manual to service a Lincoln, right? If you need to import SVG files as components check out [gatsby-plugin-svgr](https://www.gatsbyjs.com/plugins/gatsby-plugin-svgr/) (of which I am a co-author) and follow the documentation in the README. Otherwise ditch the plugin and follow the strategy shown in the answer. – coreyward Oct 12 '20 at 16:26
  • Even thou the answer is good and it works, I'm wondering why would one go this route when the gatsby site suggest using the static folder? Not trying to be a pest but I'm really interested in knowing. – FabricioG Dec 21 '20 at 22:59
  • @FabricioG It does not suggest using the static folder for this. – coreyward Dec 21 '20 at 23:30
11

You will need a static folder that has images outside the src folder in your project.

Basically it will be

my-app 
- src
-- components
--- styles.scss
- static
-- images
--- image.png

to access the image in your styles.css or scss you can just do this

background: url('/images/image.png');

or you can access the image in one of your jsx/js files by importing withPrefix from gatsby

import { withPrefix } from 'gatsby';
<div style={{ backgroundImage: `url(${withPrefix('/images/image.png')})` }} />
xxcheckmatexx
  • 113
  • 1
  • 6
3

Make sure you have the correct path defined with the path being relative to wherever your CSS file is, so the path depends on your file structure. It might be something like background-image: url('../../imageAssets/coolImages/background.png');

Nunchucks
  • 1,182
  • 10
  • 14