222

I have some problem with my images on my react project. Indeed I always thought that relative path into src attribute was built on the files architecture

Here my files architecture:

components
    file1.jsx
    file2.jsx
    file3.jsx
container
img
js 
... 

However I realized that the path is built on the url. In one of my component (for example into file1.jsx) I have this:

localhost/details/2
<img src="../img/myImage.png" /> -> works

localhost/details/2/id
<img src="../img/myImage.png" /> -> doesn't work, images are not displayed

How is it possible to solve this problem? I want that in any form of routes handled by react-router, all images can be displayed with the same path.

onedkr
  • 3,226
  • 3
  • 21
  • 31

14 Answers14

462

In create-react-app relative paths for images don't seem to work. Instead, you can import an image:

import logo from './logo.png' // relative path to image 

class Nav extends Component { 
    render() { 
        return ( 
            <img src={logo} alt={"logo"}/> 
        )  
    }
}
isherwood
  • 58,414
  • 16
  • 114
  • 157
claireablani
  • 7,804
  • 5
  • 16
  • 19
  • 50
    what about dynamic images, for instance, referenced in a json file, in create-react-app? – zok May 02 '17 at 14:47
  • 2
    @zok I think you would export the variable from the JSON file, import the variable into your component. Then you can reference it as usual. e.g. export const my_src = variable_here, import {my_src} from my_file, and src={my_src}. – claireablani May 03 '17 at 20:30
  • 2
    `import './styles/style.less'; **import logo from './styles/images/deadline.png';**` I am getting error on 2nd line module not found while image exists & path is correct. – Hitendra Jun 22 '17 at 20:52
  • This method is also confirmed by by [survive.js](https://survivejs.com/webpack/loading/images/#referencing-to-images) if you want to take a look at one of the core webpack author's methods. He also mentions you can use [babel-plugin-transform-react-jsx-img-import](https://www.npmjs.com/package/babel-plugin-transform-react-jsx-img-import) to get around having to import the image every time you reference an image. – a_dreb Mar 21 '18 at 23:11
  • 2
    Not this, it solves only image issue but does not solve the path issue.. Dima Gershman' answer is the actual react solution for path of any file img or else – Sami Apr 09 '18 at 08:39
  • This is the best practice for me who used for dummy image which located in the same root folder – AndriyFM Mar 16 '20 at 09:18
  • In my case, Even json file is dynamic and logo can we fetched from either A or B file depends on condition. How can solve this case with your approach? FYI: I don't want to use multiple import because we have many client lets say 1000, in that case if we go with this approach we will end up using import statement 1000 times! for using logo conditionally. – Piyush N Oct 21 '20 at 17:04
  • Check [create-react-app/adding-images..](https://create-react-app.dev/docs/adding-images-fonts-and-files/) documentation for more. – Soon Santos Oct 30 '20 at 14:23
224

If you used create-react-app to create your project then your public folder is accessible. So you need to add your image folder inside the public folder.

public/images/

<img src="/images/logo.png" />

Rubel hasan
  • 2,522
  • 1
  • 13
  • 22
  • 3
    It worked for me. Just remember that you need to restart the app if you added new image to the public directory. – awasik Nov 04 '19 at 11:41
  • It is indeed a fast way to treat the situations, but it will work only if you don't need relative URLs. E.g. if you serve your app at `www.example.com/react-app`, the public folder will be exposed on www.example.com, without `react-app`. This can be troublesome, so the accepted answer is the correct one. Sources: [adding assets](https://create-react-app.dev/docs/adding-images-fonts-and-files/) and [using public folder](https://create-react-app.dev/docs/using-the-public-folder/) – Alexandru Pirvu Apr 27 '20 at 17:42
98

You're using a relative url, which is relative to the current url, not the file system. You could resolve this by using absolute urls

<img src ="http://localhost:3000/details/img/myImage.png" />

But that's not great for when you deploy to www.my-domain.bike, or any other site. Better would be to use a url relative to the root directory of the site

<img src="/details/img/myImage.png" />

prekolna
  • 1,525
  • 11
  • 16
  • 3
    Thanks, I would emphasize the `/` that precedes `details` (vs `./details`, etc, for others who may conflate the two). – user1322092 Dec 30 '16 at 17:39
  • 2
    Even for me it's not working. I am using `reactjs` with `cordova` and using `ES5` as eslint – Jimit Patel May 08 '18 at 07:19
  • 2
    While both this and claireablani's solution work, claireablani's is what the create-react-app docs recommend. They list a number of benefits over putting the resources in public https://facebook.github.io/create-react-app/docs/using-the-public-folder#adding-assets-outside-of-the-module-system – Athir Nuaimi Jan 22 '19 at 18:56
  • @user1322092 is right. Remember it's `/images/popcorn.png` and not `./images/popcorn.png`. Worked for me with all the routes and stuff. – Nuhman Jun 22 '19 at 05:54
  • the / will follow the component url, not work – mercury May 02 '21 at 02:11
  • 1
    like @Dima mentioned below, if you used `create-react-app` then you can place the images in `public->myImgFolder->myImg.png` folder and use it as `{"logo"}/` – rainversion_3 Jun 07 '21 at 22:28
  • rainversion_3 it is work dude – Mr How Jan 19 '23 at 18:57
74

With create-react-app there is public folder (with index.html...). If you place your "myImage.png" there, say under img sub-folder, then you can access them through:

<img src={window.location.origin + '/img/myImage.png'} />
Sunil Garg
  • 14,608
  • 25
  • 132
  • 189
Dima G
  • 1,945
  • 18
  • 22
  • 8
    This should be marked as the correct answer, because it is actually reactjs solution for all types of paths of any files – Sami Apr 09 '18 at 08:41
  • I don't understand why you think this is the correct answer. I just tried this answer and Claireblani's answer and claire's answer worked while this did not. This answer only works if the image is in the public folder. Should my images go in the public folder? @Sami – Maderas Aug 15 '18 at 04:00
  • Yes @Maderas first things is is this answer is same as the accepted one => just removing {} and base url you can use simply src='/relative path of image' or src='absolute path of image' Whats more in this answer is that it accommodates variable path for any image – Sami Aug 15 '18 at 06:26
  • So far works for me like a charm. Nothing else did! And I tried just about everything. Thanks! – Maria Campbell Mar 30 '20 at 05:08
47

If the image is placed inside the 'src' folder, use the following:

<img src={require('../logo.png')} alt="logo" className="brand-logo"/>
Zudian
  • 105
  • 2
Prince Sodhi
  • 2,845
  • 2
  • 21
  • 35
41
  1. Make an images folder inside src(/src/images) And keep your image in it. Then import this image in your component(use your relative path). Like below-

    import imageSrc from './images/image-name.jpg';

    And then in your component.

    <img title="my-img" src={imageSrc} alt="my-img" />

  2. Another way is to keep images in public folder and import them using relative path. For this make an image folder in public folder and keep your image in it. And then in your component use it like below.

    <img title="my-img" src='/images/my-image.jpg' alt="my-img" />

    Both method work but first one is recommended because its cleaner way and images are handled by webpack during build time.

Mustkeem K
  • 8,158
  • 2
  • 32
  • 43
21

Some older answers din't work, others are good but won't explain the theme, in summary:

If image is in 'public' directory

Example: \public\charts\a.png

In html:

<img id="imglogo" src="/charts/logo.svg" />

In JavaScript:

Create image to new img, dynamically:

var img1 = document.createElement("img");  
img1.src = 'charts/a.png';  

Set image to existing img with id as 'img1', dynamically:

document.getElementById('img1').src = 'charts/a.png';

If image is in 'src' directory:

Example: \src\logo.svg

In JavaScript:

import logo from './logo.svg';  
img1.src = logo;  

In jsx:

<img src={logo} /> 
Manohar Reddy Poreddy
  • 25,399
  • 9
  • 157
  • 140
9

I have used it this way and it worked perfectly

import Product from "../../images/product-icon.png";
import { Icon } from "@material-ui/core";

<Icon>
    <img src={Product} style={{ width: "21px", height: "24px" }} />
</Icon>
5

Adding file-loader npm to webpack.config.js per its official usage instruction like so:

config.module.rules.push(
    {
        test: /\.(png|jpg|gif)$/,
        use: [
            {
                loader: 'file-loader',
                options: {}
            }
        ]
    }
);

worked for me.

Treefish Zhang
  • 1,131
  • 1
  • 15
  • 27
3

Import Images in your component

import RecentProjectImage_3 from '../../asset/image/recent-projects/latest_news_3.jpg'

And call the image name on image src={RecentProjectImage_3} as a object

 <Img src={RecentProjectImage_3} alt="" />
iamtheasad
  • 1,017
  • 13
  • 15
2

A friend showed me how to do this as follows:

"./" works when the file requesting the image (e.g., "example.js") is on the same level within the folder tree structure as the folder "images".

AdamJSim
  • 113
  • 1
  • 8
1

Place the logo in your public folder under e.g. public/img/logo.png and then refer to the public folder as %PUBLIC_URL%:

<img src="%PUBLIC_URL%/img/logo.png"/>

The use of %PUBLIC_URL% in the above will be replaced with the URL of the public folder during the build. Only files inside the public folder can be referenced from the HTML.

Unlike "/img/logo.png" or "logo.png", "%PUBLIC_URL%/img/logo.png" will work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running npm run build.

Sami Start
  • 1,755
  • 15
  • 9
0

If your page url contains multiple / then in src go back / count minus 1 times.

For example page url http://localhost:3000/play/game/ then src url must be ../your-image-folder/image-name. And your your-image-folder must be in public folder.

Muzaffer
  • 107
  • 8
0

I create my app with create-react-app and I use require instruction if I want to change dynamically my image src:

export const MyComponent = () => {
  const [myImg, setMyImg] = useState(require('./path/to/my/img'));

  const handleClick = () => {
    setMyImg(require('./path/to/other/img'));
  }

  return (
    <div>
      <img src={myImg} alt='myImg' />
      <button onClick={handleClick}>Click me!<button/>
    <div>
  )
}
Nicolas Bodin
  • 1,431
  • 1
  • 20
  • 25