Search code examples
javascriptcssreactjsgatsbyemotion

Gatsby set background-image CSS-In-JS (Emotion)


No background-image visible with the setup below. As a debugging step, I have tried setting background: pink within const background and this does work, confirming that emotion is running correctly.

When opening React Dev Tools extension I can see background-image: url(../images/page_backgroundgradient.png), url(../images/page_background.png);applied without an error.

What could my issue be please?

My file structure looks like below:

frontend/
  src/
    images/
      page_background.png
      page_backgroundgradient.png
    pages/
      index.js

My index.jsthat I am trying to add a background image to.

...
import { css, Global } from "@emotion/core"


const background = css`
  background-image: url(../images/page_backgroundgradient.png), url(../images/page_background.png);
`
<div css={background}>
   ...
</div>

Solution

  • So as stated in the link you posted in the comment, there's multiple ways to include image/assets with gatsby:

    1. Query the image from graphql
    2. import the image, get path
    3. Copy the image to static directory

    Set up

    Say you have a component like this:

    // src/pages/sample.js
    
    import React from 'react'
    import { css } from '@emotion/core'
    
    export default () => <div css={css`
      width: 10rem;
      height: 10rem;
      background: url( ... );
    `} />
    
    

    Query it

    PublicURL

    If you're using any of the default starters, it's likely that your src/images folder has been set up with gatsby-source-file-system so Gatsby know about your images. Say you know the name of the file, you can query it like so:

    {
    //       ⇣ `base` is file name with extension.
      file (base: { eq: "image.png" }) {
        publicURL
      }
    }
    

    As described in the link, querying the field publicURL will give you the path to the file name:

    export default ({ data }) => <div css={css`
      width: 10rem;
      height: 10rem;
      background: url(${data.file ? data.file.publicURL : 'your/fallback.png'});
    `} />
    
    export const query = graphql`
      query {
        file(base: { eq: "image.png" }) {
          publicURL
        }
      }
    `
    

    ImageSharp

    Gatsby usually comes with sharp, which allows you to transform images & more. For a simple example, this query resize the image to 200px width:

    export const query = graphql`
      query {
        file(base: { eq: "image.png" }) {
          childImageSharp {
            fixed(width: 200) {
              src
            }
          }
        }
      }
    `
    

    And you can access it at data.file.childImageSharp.fixed.src.

    Import the image

    Let webpack handle it:

    import myImagePath from '../relative/path/to/image.png';
    
    export default () => <div css={css`
      width: 10rem;
      height: 10rem;
      background: url(${myImagePath});
    `} />
    

    Copy it to static directory

    Create a directory named static at your root folder, unless there's one already. Copy your image into it:

    root
      |--src
      `--static
           `--image.png
    

    All files in static will be copy directly to build, so you can link to the image like this:

    export default () => <div css={css`
      width: 10rem;
      height: 10rem;
      background: url(/image.png);
    `} />
    

    If you're using pathPrefix in gatsby-config.js, import withPrefix from gatsby and wrap it around the image path.


    Here's a codesandbox for the first 2 methods.

    Hope that helps!