[javascript] React won't load local images

I am building a small react app and my local images won't load. Images like placehold.it/200x200 loads. I thought maybe it could be something with the server?

Here is my App.js

import React, { Component } from 'react';

class App extends Component {
    render() {
        return (
            <div className="home-container">
                <div className="home-content">
                    <div className="home-text">
                        <h1>foo</h1>
                    </div>
                    <div className="home-arrow">
                        <p className="arrow-text">
                            Vzdelání
                        </p>
                        <img src={"/images/resto.png"} />
                    </div>
                </div>
            </div>
        );
    }
}

export default App;

index.js:

import React, { Component } from 'react';
import { render } from 'react-dom';
import { Router, Route, Link } from 'react-router';
import { createHistory } from 'history';
import App from './components/app';

let history = createHistory();

render(
    <Router history={history} >
        <Route path="/" component={App} >
            <Route path="vzdelani" component="" />
            <Route path="znalosti" component="" />
            <Route path="prace" component="" />
            <Route path="kontakt" component="" />
        </Route>
        <Route path="*" component="" />
    </Router>,
    document.getElementById('app')
);

and server.js:

var path = require('path');
var express = require('express');
var webpack = require('webpack');
var config = require('./webpack.config.dev');

var app = express();
var compiler = webpack(config);

app.use(require('webpack-dev-middleware')(compiler, {
  noInfo: true,
  publicPath: config.output.publicPath
}));

app.use(require('webpack-hot-middleware')(compiler));

app.get('*', function(req, res) {
  res.sendFile(path.join(__dirname, 'index.html'));
});

app.listen(3000, 'localhost', function(err) {
  if (err) {
    console.log(err);
    return;
  }

  console.log('Listening at http://localhost:3000');
});

This question is related to javascript reactjs

The answer is


When using Webpack you need to require images in order for Webpack to process them, which would explain why external images load while internal do not, so instead of <img src={"/images/resto.png"} /> you need to use <img src={require('/images/image-name.png')} /> replacing image-name.png with the correct image name for each of them. That way Webpack is able to process and replace the source img.


Here is how I did mine: if you use npx create-react-app to set up you react, you need to import the image from its folder in the Component where you want to use it. It's just the way you import other modules from their folders.

So, you need to write:

import myImage from './imageFolder/imageName'

Then in your JSX, you can have something like this: <image src = {myImage} />

See it in the screenshot below:

import image from its folder in a Component


I will share my solution which worked for me in a create-react-app project:

in the same images folder include a js file which exports all the images, and in components where you need the image import that image and use it :), Yaaah thats it, lets see in detail

folder structure with JS file

// js file in images folder
export const missing = require('./missingposters.png');
export const poster1 = require('./poster1.jpg');
export const poster2 = require('./poster2.jpg');
export const poster3 = require('./poster3.jpg');
export const poster4 = require('./poster4.jpg');

you can import in you component: import {missing , poster1, poster2, poster3, poster4} from '../../assets/indexImages';

you can now use this as src to image tag.

Happy coding!


Best way to load local images in react is as follows

For example, Keep all your images(or any assets like videos, fonts) in the public folder as shown below.

enter image description here

Simply write <img src='/assets/images/Call.svg' /> to access the Call.svg image from any of your react component

Note: Keeping your assets in public folder ensures that, you can access it from anywhere from the project, by just giving '/path_to_image' and no need for any path traversal '../../' like this


src={"/images/resto.png"}

Using of src attribute in this way means, your image will be loaded from the absolute path "/images/resto.png" for your site. Images directory should be located at the root of your site. Example: http://www.example.com/images/resto.png


Another way to do:

First, install these modules: url-loader, file-loader

Using npm: npm install --save-dev url-loader file-loader

Next, add this to your Webpack config:

module: {
    loaders: [
      { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' }
    ]
  }

limit: Byte limit to inline files as Data URL

You need to install both modules: url-loader and file-loader

Finally, you can do:

<img src={require('./my-path/images/my-image.png')}/>

You can investigate these loaders further here:

url-loader: https://www.npmjs.com/package/url-loader

file-loader: https://www.npmjs.com/package/file-loader


I started building my app with create-react-app (see "Create a New App" tab). The README.md that comes with it gives this 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 worked perfectly for me. Here's a link to the master doc for that README, which explains (excerpt):

...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: bmp, gif, jpg, jpeg, and png...


Sometimes you may enter instead of in your image location/src: try

./assets/images/picture.jpg

instead of

../assets/images/picture.jpg

I faced the same issue, and I found out the problem was the location of my images. Instead of saving them into the src folder, you should store them in the public directory and have direct access.

Kudos.


By doing a simple import you can access the image in React

import logo from "../images/logo.png";
<img src={logo}/>

Everything solved! Just a simple fix =)


I too would like to add to the answers from @Hawkeye Parker and @Kiszuriwalilibori:

As was noted from the docs here, it is typically best to import the images as needed.

However, I needed many files to be dynamically loaded, which led me to put the images in the public folder (also stated in the README), because of this recommendation below from the documentation:

Normally we recommend importing stylesheets, images, and fonts from JavaScript. The public 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.
  • Some library may be incompatible with Webpack and you have no other option but to include it as a tag.

Hope that helps someone else! Leave me a comment if I need to clear any of that up.


you must import the image first then use it. It worked for me.


import image from '../image.png'

const Header = () => {
   return (
     <img src={image} alt='image' />
   )
}



I am developing a project which using SSR and now I want to share my solution based on some answers here.

My goals is to preload an image to show it when internet connection offline. (It may be not the best practice, but since it works for me, that's ok for now) FYI, I also use ReactHooks in this project.

  useEffect(() => {
    // preload image for offline network
    const ErrorFailedImg = require('../../../../assets/images/error-review-failed.jpg');
    if (typeof window !== 'undefined') {
      new Image().src = ErrorFailedImg;
    }
  }, []);

To use the image, I write it like this

<img src="/assets/images/error-review-failed.jpg" />

Here is what worked for me. First, let us understand the problem. You cannot use a variable as argument to require. Webpack needs to know what files to bundle at compile time.

When I got the error, I thought it may be related to path issue as in absolute vs relative. So I passed a hard-coded value to require like below: <img src={require("../assets/images/photosnap.svg")} alt="" />. It was working fine. But in my case the value is a variable coming from props. I tried to pass a string literal variable as some suggested. It did not work. Also I tried to define a local method using switch case for all 10 values (I knew it was not best solution, but I just wanted it to work somehow). That too did not work. Then I came to know that we can NOT pass variable to the require.

As a workaround I have modified the data in the data.json file to confine it to just the name of my image. This image name which is coming from the props as a String literal. I concatenated it to the hard coded value, like so:

import React from "react";

function JobCard(props) {  

  const { logo } = props;
  
  return (
      <div className="jobCards">
          <img src={require(`../assets/images/${logo}`)} alt="" /> 
      </div>
    )
} 
  

The actual value contained in the logo would be coming from data.json file and would refer to some image name like photosnap.svg.


Actually I would like to comment, but I am not authorised yet. That is why that pretend to be next answer while it is not.

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" />;

I would like to continue that path. That works smoothly when one has picture one can simple insert. In my case that is slightly more complex: I have to map several pictures it. So far the only workable way to do this I found is as follows

import upperBody from './upperBody.png';
import lowerBody from './lowerBody.png';
import aesthetics from './aesthetics.png';

let obj={upperBody:upperBody, lowerBody:lowerBody, aesthetics:aesthetics, agility:agility, endurance:endurance}

{Object.keys(skills).map((skill) => {
 return ( <img className = 'icon-size' src={obj[skill]}/> 

So, my question is whether are there simplier ways to process these images? Needless to say that in more general case number of files that must be literally imported could be huge and number of keys in object as well. (Object in that code is involved clearly to refer by names -its keys) In my case require-related procedures have not worked - loaders generated errors of strange kind during installation and shown no mark of working; and require by itself has not worked neither.


I just wanted to leave the following which enhances the accepted answer above.

In addition to the accepted answer, you can make your own life a bit easier by specifying an alias path in Webpack, so you don't have to worry where the image is located relative to the file you're currently in. Please see example below:

Webpack file:

module.exports = {
  resolve: {
    modules: ['node_modules'],
    alias: {
      public: path.join(__dirname, './public')
    }
  },
}

Use:

<img src={require("public/img/resto.ong")} />

Try changing the code in server.js to -

app.use(require('webpack-dev-middleware')(compiler, {
      noInfo: true,
      publicPath: config.output.path
    }));