Setting background image in React using SCSS / Webpack

I’m having trouble setting a background image for a react app, using SCSS.

My app has the following structure, with most files removed for readability:

--node_modules
--public
----index.html
----bg-img.jpg
--src
----components
----styles
------base
--------_base.scss
--------_settings.scss
------components
------styles.scss
----app.js

I’m trying to reference the bg-img.jpg in the public folder with

background-image: url('bg-img')

in the _base.scss file.

The console complains that the image is not there. I’ve also tried url('../../../public/bg-img.jpg') and some other variations.

I think I need to wire up a loader in webpack. I tried url-loader and some copypasta webpack config:

{
      test: /\.(jpg|png)$/,
      loader: "url-loader?limit=25000",
      //loader: 'file?name=[path][name].[ext]',
      include: path.join(__dirname, 'public')
    },

but I had no luck with this.

I feel like this shouldn’t be hard…so does anyone know how to go about doing this?!

Have you tried url('../../public/bg-img.jpg')?

I did. That was actually the path that led me to look into loaders. By ‘variations’ above, I meant I tried all reasonable versions of ../ and ../.. and ../../.. and so on :wink:

The error message for the sake of all the information:

Module parse failed: /home/jackson/dev/fcc-recipe-react/public/bg-img.jpg Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type.
(Source code omitted for this binary file)
 @ ./node_modules/css-loader!./node_modules/sass-loader/lib/loader.js!./src/styles/styles.scss 6:125-159
 @ ./src/styles/styles.scss
 @ ./src/app.js
 @ multi (webpack)-dev-server/client?http://localhost:8080 ./src/app.js

I found this on stack overflow:

In your webpack config file use url-loader in loaders

{
  test: /\.(png|jpg)$/,
  loader: 'url-loader'
}

I tried this on your repo and it compiled successfully (using ../..).

I also tried your loader snippet and it too seems to work.

I recently had used this in scss and it worked fine for me
background: url(’/images/backscreen.png’);

my compiled css file was however in the same folder as my scss file, i cant see where your compiled css file is at and how your index.html file is pointing to it at, other than that dont see what the problem is , you can look at my file structure

Hmm, still not working for me.

This is my webpack config:

webpack.config
const path = require('path');

module.exports = {
  entry: './src/app.js',
  output: {
    path: path.join(__dirname, 'public'),
    filename: 'bundle.js'
  },
  module: {
    rules: [{
      loader: 'babel-loader',
      test: /\.js$/,
      exclude: /node_modules/
    }, {
      test: /\.s?css$/,
      use: [
        'style-loader', 
        'css-loader',
        'sass-loader'
      ]
    }, {
      
    }],
    loaders: [
      { 
        test: /\.(png|jpg)$/,
        loader: 'url-loader' 
     } 
    ]
  }, 
  devtool: "cheap-module-eval-source-map",
  devServer: {
    contentBase: path.join(__dirname, 'public')
  }
};

And _base.scss has this:

body {
  background-color: $puff;
  background-image: url('../../public/bg-img.jpg');
  font-family: $sans;
}

And url-loader has been yarn added…what’s the obvious thing I’m missing?

Sorry, that was @kevcomedia

I think the url-loader object should be in the rules array, not in a separate loaders one.

Ok, I think I’ve got it.

It was a combination of the above and needing to restart webpack dev server between fiddling with the loaders.

Now my issue is that the image I’m using is too big to be base64 encoded, I think.

But at least it’s progress.

Hi @JacksonBates ,
Would you mind sharing how did you set up the background Image. What changes did you make?So I have my webpack correctly configured , however I am unable to set a background Image to my header component.

I had the same problem recently and fixed it by setting url-loader for jpg, png, gif or whatever other format you’re using, then setting relative path to the image in your css/scss like you would usually do and then restarting webpack as Jackson mentioned.

The code for setting url-loader:

module: {
  rules: [
    {
      test: /\.(png|jpg|gif)$/,
      loader: 'url-loader'
    }
  ]
}
1 Like

I actually changed mine in the end to use a CDN hosted image. Having the image loaded in via webpack really bulks up the file size of the final bundle, and it was taking too long to load.

src={window.location.origin + ‘/images/logo.png’}
is good for image in yr header component

So let me see if I get this right, in order to set image as background in scss files using Webpack, I have to change Webpack configuration? Otherwise I have to use inline styles directly in the component?

Configuring webpack is one option, but as discussed above, it makes the bundle size large.

My solution in the end was to use a hosted image, linked to from the style sheet, not inline. Check out the github file above for the example.

Is there anything wrong with just using inline styles directly in the React component?

import home from "../img/home/home-1.jpg";

const bg = {
    backgroundImage: `linear-gradient(to bottom, rgba(205, 169, 157, 0.7), rgba(205, 169, 157, 0.7)),
  url(${home})`
  };

This is how I’ve been doing it since I haven’t been able to find a way to do this in the scss file.

This worked perfectly for me, thanks!

1 Like

Haha! after some tweaking and no luck, had to read your comment and reload, and voila it worked!

Use this,

background: url(‘http://localhost:3000/bg-img.jpg’);

for local dev

works fine

Hi @baradraja!

Welcome to the forum!

Thank you for your answer however this post is two years old. Please try to comment on newer posts.

Thanks!