Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Requiring images with dynamic paths #16

Closed
amytych opened this issue Apr 19, 2018 · 9 comments
Closed

Requiring images with dynamic paths #16

amytych opened this issue Apr 19, 2018 · 9 comments

Comments

@amytych
Copy link

amytych commented Apr 19, 2018

Is it possible to require images with dynamically created paths? E.g.:

import React from 'react';

export default ({ imgName }) => (
  <div>
    <img src={require(`./images/${imgName}`)} />
  </div>
);

Something along the lines described in this article https://medium.com/@bogdan_plieshka/loading-static-and-dynamic-images-with-webpack-8a933e82cb1e

Thanks for any help!

@cyrilwanner
Copy link
Owner

Hi @amytych

Yes, in my project, this code is working:

import React from 'react';

export default () => (
  <div className={styles.Row}>
    {
      [1, 2, 3].map(imageId => (
        <img key={imageId} src={require(`./assets/images/dynamic/image-${imageId}.jpeg`)} />
      ))
    }
  </div>
);

I now even created the same component you posted, and it is working too for me.
Do you get any error during build or request?

@kotay
Copy link

kotay commented Jul 2, 2018

This works great, how can I get this to work with query parameters (?webp), the following does not seem to work:


import React from 'react';

export default () => (
  <div className={styles.Row}>
    {
      [1, 2, 3].map(imageId => (
        <img key={imageId} src={require(`./assets/images/dynamic/image-${imageId}.png?webp`)} />
      ))
    }
  </div>
);

@aulneau
Copy link

aulneau commented Jul 12, 2018

I am also getting an issue importing images dynamically when appending the path with -> ?webp

@cyrilwanner
Copy link
Owner

Unfortunately, I still haven't found a solution yet and I actually think this is a limitation or bug of webpack as other projects also have this problem and I couldn't find a working solution on the internet.
I currently have one idea left which I would want to try, but if this also won't work, I'll create an issue in the webpack repository to ask for help.
I'll keep you posted and sorry for the inconveniences.

@cyrilwanner
Copy link
Owner

And as a temporary solution (I know it is a bit verbose and not clean, I'll still try to find a solution to this issue), something like this should work in the meantime:

const images = {
  id1: require('./assets/images/dynamic/image-id1.png?webp'),
  id2: require('./assets/images/dynamic/image-id2.png?webp'),
  id3: require('./assets/images/dynamic/image-id3.png?webp'),
  id4: require('./assets/images/dynamic/image-id4.png?webp'),
  // ...
};

export default () => (
  <div className={styles.Row}>
    {
      ['id1', 'id2', 'id3', 'id4'].map(imageId => (
        <img key={imageId} src={images[imageId]} />
      ))
    }
  </div>
);

@cyrilwanner
Copy link
Owner

Hello everyone and sorry for the late reply.
I found an undocumented parameter within require.context which resolves our problem.

We can add resource queries to the first argument of require.context where the directory is specified.
The example @kotay posted would now look like this:

import React from 'react';

const requireWebpImage = require.context('./assets/images/dynamic?webp', false, /\.png$/);

export default () => (
  <div className={styles.Row}>
    {
      [1, 2, 3].map(imageId => (
        <img key={imageId} src={requireWebpImage(`./image-${imageId}.png`)} />
      ))
    }
  </div>
);

You maybe have to change the parameters of require.context (see the docs), but for me, it worked in my example project. Does this also work for your use-cases?

@james-wallis
Copy link

james-wallis commented Aug 26, 2018

Ran in to this problem earlier. I was unable to use a totally dynamic path.

This didn't work:

const sauce = '../../images/background.jpg';
<img src={require(`${sauce}`)} />

But this did work:

const sauce = 'background.jpg';
<img src={require(`../../images/${sauce}`)} />

Also relevant if you're using dynamic paths: #141 (comment)

@DenisOleksiuk
Copy link

In my case it was helps me

  const burgerIcon = isOpen ? (
    <img src={require('../../../public/close_black_24dp.svg')} />
  ) : (
    <img src={require('../../../public/menu_black_24dp.svg')} />
  );

@rjlg
Copy link

rjlg commented May 27, 2021

Hello everyone and sorry for the late reply.
I found an undocumented parameter within require.context which resolves our problem.

We can add resource queries to the first argument of require.context where the directory is specified.
The example @kotay posted would now look like this:

import React from 'react';

const requireWebpImage = require.context('./assets/images/dynamic?webp', false, /\.png$/);

export default () => (
  <div className={styles.Row}>
    {
      [1, 2, 3].map(imageId => (
        <img key={imageId} src={requireWebpImage(`./image-${imageId}.png`)} />
      ))
    }
  </div>
);

You maybe have to change the parameters of require.context (see the docs), but for me, it worked in my example project. Does this also work for your use-cases?

Thanks! This resolved my issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants