241

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">
                            Vzdělá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');
});
Penny Liu
  • 15,447
  • 5
  • 79
  • 98
Petrba
  • 2,443
  • 2
  • 10
  • 6
  • 4
    This usually means your local web server is not serving the images or the url you specified is incorrect. Open your browser console and check if you get any errors such as 404 not found. – Mario Tacke Jan 03 '16 at 22:35

24 Answers24

453

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.

danronmoon
  • 3,814
  • 5
  • 34
  • 56
Thomas
  • 5,110
  • 1
  • 16
  • 17
  • 1
    But how to import require? Browserify? If yes, then how? I have tried `import {require} from 'browserify'`. But it's not working. – Shubham Kushwah Jun 14 '18 at 08:14
  • 3
    @ShubhamKushwah You should not have to import `require`. It is provided as part of `commonjs`. See https://stackoverflow.com/a/33251937/4103908 and https://www.viget.com/articles/gulp-browserify-starter-faq/ for further details that might help you using require and browserify using Gulp. – Thomas Jun 14 '18 at 12:38
  • @Thomas The problem is with internal as well as external images, they won't load when the page first loads, but if I refresh it, they will load. So how should I resolve this - Please help! – Shubham Kushwah Jun 15 '18 at 11:35
  • 17
    Getting an error: `Module not found: Error: Can't resolve 'MyPNG.png' in 'C:...\app\components\images'`. The path to the file looks good!. – reubenjohn Aug 06 '18 at 10:51
  • I'm want to do this via `import` instead of `require`. Is this possible? I tried it and the only way to get it to compile is by doing `import('image/myImage.jpg')`, but even so, the image would not show up. Using `require` however, does not have this issue. – Alex Wang Oct 25 '18 at 03:37
  • 3
    src= {require('./reactLogo.svg')} start your path with " ./ " for the current directory to avoid errors. – cheesey Apr 30 '19 at 03:15
  • As @cheesey has mentioned "./" resolved my issue, "./" is current directory – Vishwanath Feb 27 '20 at 06:26
  • works like a charm – 0xe1λ7r Jul 20 '20 at 08:37
  • I have same issue. I tried using "require" and the images were displaying properly. But now Idk why it suddenly stopped displaying. Can anyone help with this issue even after using require. I also saw the console and there was no error, but It displayed this in the console.... " [HMR] Waiting for update signal from WDS..." –  Nov 30 '20 at 14:22
  • This isn't working for me. My images are located at `src/images`. Please help. In the documentation it seemed like they don't recommend people placing images in the public directory? I'm not sure? But they also don't specify how to import multiple images from src either! Like importing objects which contain image paths and mapping through them. Neither require nor import is working for me in this case. – Akhila Jan 10 '21 at 14:40
  • 3
  • What if React just stopped resolving image paths? I've copied this app data to a new project, and it seemed to find the images. The original project though just stopped doing that. – 101is5 Nov 24 '22 at 21:47
156

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...

Hawkeye Parker
  • 7,817
  • 7
  • 44
  • 47
  • In addition, you have to also be exporting the images from somewhere in order to be able to import them anywhere and not just from within the same directory, Which is what would be the case if they were not being exported. They would have to reside in the same directory as the component they were being imported into. You will notice that with any new React app created with CRA for example, the logo.svg file resides in the same directory as App.js, where it is imported. I wrote a piece on importing images in React here: https://blog.hellojs.org/importing-images-in-react-c76f0dfcb552 – Maria Campbell Oct 30 '17 at 23:46
  • To follow up on the comment above, if you use webpack url-loader as fandro shows above, you files that match test extensions in webpack are automatically exported and make them available to import the save Hawkeye Parker has shown above. – dave4jr Apr 14 '18 at 23:59
  • I know this is a really old topic but still ; how did you make that work? In my case, program is trying to "read the image"... resulting in an awful error: `Unexpected character '�' (1:0) > 1 | �PNG | ^ 2 | 3 | 4 | IHDR��r~ipHYs���o�d��IDATx^�}���Ü�d7�w¿½ï¿½ ��JzH!�K�ï` ... – V. Courtois Aug 28 '18 at 14:43
  • @V.Courtois sorry -- I haven't worked with this stuff since then, and I don't remember any more details right now :( – Hawkeye Parker Aug 29 '18 at 17:25
  • 1
    I had to add my images to the public folder in the Create-React-App project. – pixel 67 Sep 28 '18 at 15:49
  • If you are using Webpack + React + Typescript have a look at https://github.com/Microsoft/TypeScript-React-Starter/issues/12#issuecomment-326370098 . This solved the problem for me! – Janis Jansen Feb 12 '19 at 09:51
  • 1
    This worked for me, for some reason the ./ before the name file is required – NDUF Mar 20 '19 at 06:20
40

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

Mokesh S
  • 683
  • 6
  • 11
  • PNG image wont work on this? Bcuz I did exactly this and it didnt work. – maverick Jun 14 '20 at 18:53
  • PNG will also work. Did SVG is working for you? Please do the spell check of the file name and reassure that image path is correct. – Mokesh S Jun 17 '20 at 17:19
  • 1
    apologies for this mistake. I was new to react and I didnt know that the component file should start with capital casing. After that it worked. – maverick Jun 17 '20 at 18:10
  • This was the problem. But I wonder why we can't access files in other folders. – Anupam Dec 31 '20 at 05:37
  • 2
    React automatically resolves the path: https://stackoverflow.com/questions/47196800/reactjs-and-images-in-public-folder – Fotios Tsakiris Aug 16 '21 at 17:13
36

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

agm1984
  • 15,500
  • 6
  • 89
  • 113
fandro
  • 4,833
  • 7
  • 41
  • 62
  • 1
    Hopefully it helps others. I had to do this as well; Install url-loader. `npm install --save-dev url-loader` – LUser May 17 '17 at 11:38
  • 1
    I was struggling with this last night, and this post was actually on my screen this morning :) If you see something like `Module build failed: SyntaxError: c:/contrivedpath/images/profile.jpg: Unexpected character '�' (1:0)`, all you need to do is add this above url-loader config to your webpack config, npm install `url-loader` AND `file-loader` and you will be functional. I tested to make sure, and file-loader is necessary. – agm1984 Sep 24 '17 at 21:17
  • 3
    @agm1984 I followed the above steps and am still getting the `ERROR in ./src/images/imagename.png Module parse failed: Unexpected character '�' (1:0)` message. Any ideas? – David Jan 03 '18 at 14:42
  • it was really useful but i am unable to understand why won't work!! Could you please explain? – Mark Feb 13 '18 at 12:58
  • Did everything you said but no dice. Webpack builds without complaining, I can see my PNG image has been moved into the output directory but the image doesn't load on the page. When I inspect the code it just say `src=[Object module]` and when I hover my mouse it says 'could not load the image' – jsstuball Feb 11 '20 at 19:28
26

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 =)

ADITHYA AJAY
  • 295
  • 3
  • 8
13

Use the default property:

<img src={require(`../../assets/pic-${j + 1}.jpg`).default} alt='pic' />

EDIT (Further explanation):

require returns an object:

Module {default: "/blah.png", __esModule: true, Symbol(Symbol.toStringTag): "Module"}

The image's path can then be found from the default property

StefanBob
  • 4,857
  • 2
  • 32
  • 38
  • 1
    Thanks, works well. Could you please care to explain what exactly does `.default` do? Because images were not loading without adding the `default` property. – Prajwal Kulkarni Mar 09 '22 at 15:49
  • 1
    @PrajwalKulkarni I updated the answer with a further explanation. Hope it helps – StefanBob Mar 09 '22 at 20:00
9

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

Aye
  • 271
  • 3
  • 9
5

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.

taurusx
  • 33
  • 3
vancy-pants
  • 1,070
  • 12
  • 13
  • man this helped me! I just felt like the documentation is confusing cuz first they discourage people from adding images to the public folder, then they talk about these exceptional scenarios - which is like the common scenario all the time - dynamically loading multiple images ! – Akhila Jan 10 '21 at 14:54
5

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' />
   )
}


Omama Zainab
  • 741
  • 4
  • 14
  • 24
4

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")} />
adamj
  • 4,672
  • 5
  • 49
  • 60
2

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

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.

Anupam
  • 428
  • 7
  • 15
2
  • First, Check whether you have specified the current location of the image or not, if you face difficulties setting the correct path , you can use this.

  • Second, Import the image just like you import any js file, Like this

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

you can name x anything!!

1

Try changing the code in server.js to -

app.use(require('webpack-dev-middleware')(compiler, {
      noInfo: true,
      publicPath: config.output.path
    }));
hazardous
  • 10,627
  • 2
  • 40
  • 52
1

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

./assets/images/picture.jpg

instead of

../assets/images/picture.jpg
Hardik Shah
  • 4,042
  • 2
  • 20
  • 41
Kean Amaral
  • 5,503
  • 2
  • 16
  • 9
1
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

zdrsoft
  • 2,417
  • 19
  • 10
1

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.

Venky4c
  • 11
  • 4
1

I RESOLVED IT THIS WAY.

So I had this issue only when I was mapping over an array with multiple images. Normally with imports import artist3 from './../../../assets/images/cards_images/artists/artist3.png'; it works fine but the issue was when looping over the multiple images form an array.

I am sharing the solution that I used to approach it.

Previously----- I was using imageurl: 'your_image_url.png'

Now------ So in my array I changed to this imageurl: require('your_image_url.png')

  const artists = [
{firstname: 'Trevor', lastname: 'Bowman', imageurl: require('./../../assets/images/cards_images/artists/artist1.png') },
{firstname: 'Julia', lastname: 'Deakin', imageurl: require('./../../assets/images/cards_images/artists/artist2.png') },
{firstname: 'Stewart', lastname: 'Jones', imageurl: require('./../../assets/images/cards_images/artists/artist3.png') },
{firstname: 'Arsene', lastname: 'Lupin', imageurl: require('./../../assets/images/cards_images/artists/artist1.png') },

 ]

Now in the other component where I used this data to loop over the artists I binded to the image src as follows

<img src={artist.imageurl.default} className="artists__content--image br-08" alt={'img'+index} />

Because when you put the require() thing you get the Module object, which has a default property and it has our url (screenshot attached below)

enter image description here

So the .default thing is the extra one only to access url after using require()

Wahab Shah
  • 2,066
  • 1
  • 14
  • 19
1

Ohhh yeahhh I had the same problem a few minutes ago and this worked for me:

import React from "react" import logo from "../images/logo.png"

export default function Navbar() {
    return(
        <nav>
            {/* <img className="nav--logo" src="../images/logo.png"/> */}
            <img className="nav--logo" src={logo} alt="logo"/>
        </nav>
    ) }
Cyebukayire
  • 795
  • 7
  • 14
0

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!

thowfeeq
  • 233
  • 2
  • 8
0

I was facing the same issue and i have figure out this solution and it works like a magic. src={${window.location.origin.toString()}/${Image name here}}

Manzoor
  • 23
  • 4
0

If you have your images folder inside the public folder, you need to try this:

<img src={process.env.PUBLIC_URL + "/images/test.jpg"}

I had the same issue and hopefully by trying this, everything just got back to normal.

When you are dealing with HTML & CSS, you can use your old method for accessing the images. but when you are in React, you are basically dealing with JSX. so this solution might be helpful for many React Programmers who are struggling with loading images in React properly.

FYI:

do you remember we had a long comment in a file called index.js which was located inside our public folder? if you don't remember which comment I'm talking about, just check out the screenshot below :

enter image description here

I thought that it might be helpful to read it cos it's actually related to this topic and issue.

Matin
  • 173
  • 2
  • 15
0

It has been solved for me by just remove "dot" from path of public images.

fady ahmed
  • 39
  • 6
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 04 '22 at 11:54
0

Try this

if your image src is

src="dist/img/logo.jpg"

add ../ like

src="../dist/img/logo.jpg"
Merrin K
  • 1,602
  • 1
  • 16
  • 27