1

i have objects with keys img and the value is relative path to image folder placed in src folder '/images'. I'm using map to loop over destructured data and adding it to DOM with simple template like this:

<div key={id}>

<img src={img + '.jpg'} alt='{title}' />
</div>

And my data object looks like this:

const category = [
  {
    id: 1,
    title: 'cizme',
    img: './images/cizme',
    link: './cizme'},
...

data(category) is defined in App component

import data from './data';
import Home from './Home';
import logo from './images/logo_fin-01.png';

import Navbar from './Navbar';

function App() {
  return (
    <div className='App'>
      <Navbar logo={logo} />
      <Home data={data} />
    </div>
  );
}

export default App;

and Home comp is:

const Home = ({ data }) => {
  return (
    <div className='kat'>
      {data.map(({ id, title, img, link }) => (
        <li key={id}>
          <span>{title}</span>
          <div className='img-container'>
            <img src={img + '.jpg'} alt={title}></img>
          </div>
        </li>
      ))}
    </div>
  );
};

export default Home;

Now, and in browser paths are displayed correctly, with no errors, but it says image 'could not load the image'.I tried to copy images folder to public but then i get error 'its out of scope or sth like this(i forgot)'.So what should i do?

update: require() works in sandbox, localy doesn't.

https://codesandbox.io/embed/zealous-christian-0j3v3?fontsize=14&hidenavigation=1&theme=dark

  • Check the network tab in the inspector. Are the correct URLs loaded? How do you serve the images? – Harald Gliebe Jun 30 '21 at 20:03
  • status: 200 OK sry, what do you think by 'serve'? – zoran lazarevic Jun 30 '21 at 20:17
  • Im importing data.js in App component, then i send props to other component where i destructure and and add img value to the DOM – zoran lazarevic Jun 30 '21 at 20:21
  • Does this answer your question? [Correct path for img on React.js](https://stackoverflow.com/questions/37644265/correct-path-for-img-on-react-js) – Janez Kuhar Jun 30 '21 at 20:23
  • No. :) i'm sure sth simple is missing... There is also logo img that i'm importing like so import logo from './images/logo_fin-01.png'; and it works. But, if i look its path in devTools its says /static/media/logo... – zoran lazarevic Jun 30 '21 at 20:36
  • Where is `category` defined? Can you update your question to include a more complete and comprehensive code example? I have something functional here in a [codesandbox](https://codesandbox.io/s/sharp-stonebraker-wm2op?file=/src/styles.css). – Drew Reese Jun 30 '21 at 20:40

2 Answers2

1

Your current approach won't work (unless you have to import the images over a loop), since you've kept these images in src folder. By keeping the image url as relative to the current folder won't work, because when passing a URL to src (and not an imported image), your browser starts rendering, the img's src attribute will look with respect to the URL, and not the folder from which the javascript file is being loaded and executed.

In other words, if my component serving this mapped image route is at the URL xyz.com/something/currentScreen, then './images/cizme' + '.jpg' will translate to xyz.com/something/images/cizme.jpg, which doesn't exist.

Since you are trying to dynamically render these images, a good way would be to place them in public folder, (and then inside 'images' folder, since your URL says so), and then have '/images/cizme' + '.jpg' which will result in xyz.com/images/cizme.jpg loading properly, because they exist inside the public folder.

Edit: Can you confirm that your browser paths are correct? Try opening Network Tab as prescribed in the comments.

Areeb Khan
  • 413
  • 3
  • 11
  • this seems ok to me. images folder is inside src folder. `stitnici` network tab: this..i dont know if its ok...? `GET http://localhost:3000/images/ostalo` – zoran lazarevic Jun 30 '21 at 21:55
  • Kindly read my answer again. I'm advising to place the images in `public` folder, as it you won't have to import the images one by one that way. [Here's a working CodeSandBox](https://codesandbox.io/s/suspicious-antonelli-obpwz?file=/src/App.js) that I made for your use case. Kindly note that you also have to append the extension of the image, which I do not see in your comment. Check out the `data.js` file to get a clarity of what I mean by that. – Areeb Khan Jul 01 '21 at 06:33
  • P.S: Kindly note that anything kept in `public` folder is not affected by webpack, and there are some downsides to it. [Read more here](https://create-react-app.dev/docs/using-the-public-folder/) – Areeb Khan Jul 01 '21 at 06:41
0

I'm assuming that since your category array is specifying local/relative paths that it's generated at compile time (and not some dynamic value at run-time), and as such, will have access to assets located in the src source directory.

You can either import all the images and specify them in the category array.

import img1 from './images/cizme.jpg';
...

const category = [
  {
    id: 1,
    title: 'cizme',
    img: img1,
    link: './cizme'
  },
...

Or since listing all the imports explicitly is impractical, you can just require them in the data.

const category = [
  {
    id: 1,
    title: 'cizme',
    img: require('./images/cizme.jpg'),
    link: './cizme'
  },
...

Then you can just render the images as per normal.

{category.map(({ id, img, title}) => (
  <div key={id}>
    <img src={img} alt='{title}' />
  </div>
))}

Update

I updated my linked codesandbox to reflect your code. If the exported data uses require to pull in the images, then Home can simply attach the img value to the src attribute.

const Home = ({ data }) => {
  return (
    <div className="kat">
      {data.map(({ id, title, img, link }) => (
        <li key={id}>
          <span>{title}</span>
          <div className="img-container">
            <img src={img} alt={title}></img>
          </div>
        </li>
      ))}
    </div>
  );
};

Edit sharp-stonebraker-wm2op

Example with cat1.jpg, cat2.jpg, and cat3.jpg images located in a "./images" directory in src.

enter image description here

Code:

data.js

const data = [
  {
    id: 1,
    title: "cizme",
    img: require("./images/cat1.jpg"),
    link: "./cizme"
  },
  {
    id: 2,
    title: "cizme",
    img: require("./images/cat2.jpg"),
    link: "./cizme"
  },
  {
    id: 3,
    title: "cizme",
    img: require("./images/cat3.jpg"),
    link: "./cizme"
  }
];

export default data;

App.js

import data from "./data";

const Home = ({ data }) => {
  return (
    <div className="kat">
      {data.map(({ id, title, img, link }) => (
        <li key={id}>
          <span>{title}</span>
          <div className="img-container">
            <img src={img} alt={title}></img>
          </div>
        </li>
      ))}
    </div>
  );
};

export default function App() {
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Edit to see some magic happen!</h2>

      <Home data={data} />
    </div>
  );
}
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • Everything looks the same except require....this is the output when i add require() is there any dependency or package i need to install or sth? Any specific import? `./src/data.js Module not found: Can't resolve './images/cizme' in '/home/zoran/Documents/web tests/sikimoto/sikimoto-app/src'` – zoran lazarevic Jun 30 '21 at 21:10
  • @zoranlazarevic Oh, sorry, I guess I neglected to mention you need to include the file extension when requiring files like this. It's in my examples but I didn't expressly call it out. – Drew Reese Jun 30 '21 at 21:11
  • so... i included require and extension, and everything looks the same.. but still i cant get them to show up! DevTools now says `` – zoran lazarevic Jun 30 '21 at 21:38
  • @zoranlazarevic Think you could try creating your own *running* codesandbox that reproduces the `[object modules]` issue on the image and share? – Drew Reese Jun 30 '21 at 21:54
  • simpliest solution is to use gphotos! Thank you for your effort! – zoran lazarevic Jul 01 '21 at 06:21
  • @zoranlazarevic I don't know what gphotos is, but glad to help any way I did. Cheers. – Drew Reese Jul 01 '21 at 06:27