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

<Image> not displaying #1497

Closed
lastant opened this issue Dec 5, 2019 · 17 comments
Closed

<Image> not displaying #1497

lastant opened this issue Dec 5, 2019 · 17 comments

Comments

@lastant
Copy link

lastant commented Dec 5, 2019

I built a project using react-native-web some years ago, and displaying images from assets used to work out of the box: <Image source={require('../assets/icon-activities.png')} /> would translate to an inline background-image: url("data:image/png;base64,.... . This is very convenient.
Now that I updated to the latest version of react-native-web, the images are not displayed at all. I learned about react-native-web-image-loader, but seems it doesn't inline the image data. Is it still possible to inline the image data?

@necolas
Copy link
Owner

necolas commented Dec 5, 2019

If you produce a test case I'll reopen. The instructions on reporting issues are clear

@necolas necolas closed this as completed Dec 5, 2019
@lastant
Copy link
Author

lastant commented Dec 12, 2019

I just firstly would like to know if this is expected behavior..

@lastant
Copy link
Author

lastant commented Mar 17, 2020

Fixed it with the following webpack config (esModule parameter):

...
const imageLoaderConfiguration = {
  test: /\.(gif|jpe?g|png|svg)$/,
  use: {
    loader: "url-loader",
    options: {
      name: "[name].[ext]",
      esModule: false,
    }
  }
};
...

@greenais
Copy link

greenais commented May 5, 2020

@lastant, thanks, you saved my day!

@jkoutavas
Copy link

jkoutavas commented Jan 18, 2021

For the life of me, I can not get this to work.

I'm on react-native-web 0.14.10 having yesterday generated an app from scratch using npx create-react-native-web-application --name myappname. I went and edited the resultant config-overrides.js file and added the following:

  addWebpackModuleRule({
    test: /\.(gif|jpe?g|png|svg)$/,
    use: {
      loader: 'url-loader',
      options: {
        name: '[name].[ext]',
        esModule: false,
      }
    }
  })

My App.tsx contains this: <Image source={require('./assets/images/AppLogoIcon.png')} />

and I have the AppLogoIcon.png file at src/assets/images.

Everything builds fine for web (yarn run web), but the image does not appear. The image appears fine on iOS and Android, as you would expect.

Everywhere I look online, I see variations of the solution that @lastant gave, in articles and replies to questions but no joy here for me. Has something changed recently in react-native-web that breaks the ability to load static images? I searched all around github hoping to see a react-native-web example app that handles static images, and found nothing, which is surprising to me (I'm pretty decent at searching, heh.) Does this mean that people just generally are not using static images? What's the best practice to share image loading code between mobile and web? I'd rather not have to conditionalize things and start using URIs for the web side, at least not for small images (< 1K).

Update: just on the off chance that create-react-native-web-application generator was producing a config problem, I simplified the creation process (and also used javascript instead of typescript). You can see the (failing) project here:
https://github.com/jkoutavas/react-native-web-static-image

@RichardLindhout
Copy link
Contributor

For the life of me, I can not get this to work.

I'm on react-native-web 0.14.10 having yesterday generated an app from scratch using npx create-react-native-web-application --name myappname. I went and edited the resultant config-overrides.js file and added the following:

  addWebpackModuleRule({
    test: /\.(gif|jpe?g|png|svg)$/,
    use: {
      loader: 'url-loader',
      options: {
        name: '[name].[ext]',
        esModule: false,
      }
    }
  })

My App.tsx contains this: <Image source={require('./assets/images/AppLogoIcon.png')} />

and I have the AppLogoIcon.png file at src/assets/images.

Everything builds fine for web (yarn run web), but the image does not appear. The image appears fine on iOS and Android, as you would expect.

Everywhere I look online, I see variations of the solution that @lastant gave, in articles and replies to questions but no joy here for me. Has something changed recently in react-native-web that breaks the ability to load static images? I searched all around github hoping to see a react-native-web example app that handles static images, and found nothing, which is surprising to me (I'm pretty decent at searching, heh.) Does this mean that people just generally are not using static images? What's the best practice to share image loading code between mobile and web? I'd rather not have to conditionalize things and start using URIs for the web side, at least not for small images (< 1K).

Update: just on the off chance that create-react-native-web-application generator was producing a config problem, I simplified the creation process (and also used javascript instead of typescript). You can see the (failing) project here:
https://github.com/jkoutavas/react-native-web-static-image

You don't have to edit the config-overrides for the image to work (in create-react-native-web-application). But you should provide the width/height to the style. It's required in React Native Web.

@jkoutavas
Copy link

jkoutavas commented Jan 18, 2021

You don't have to edit the config-overrides for the image to work (in create-react-native-web-application). But you should provide the width/height to the style. It's required in React Native Web.

Thank you for your prompt reply, @RichardLindhout .

Adding the width/height did in fact get the image to appear, and I needed to keep the url-loader in my simple project in order for it to work. You can see that change in this PR

Note: when I went back to visit my create-react-native-web-application, I DID still have to leave the url-loader in overrides for the image to appear.

@RichardLindhout
Copy link
Contributor

Hmm, that's strange it should work, what if you use.

import AppLogoIcon from '/assets/images/AppLogoIcon.png

More here:
https://create-react-app.dev/docs/adding-images-fonts-and-files

create-react-native-web-application uses create-react-app in the background

@harshilJs
Copy link

Fixed it with the following webpack config (esModule parameter):

...
const imageLoaderConfiguration = {
  test: /\.(gif|jpe?g|png|svg)$/,
  use: {
    loader: "url-loader",
    options: {
      name: "[name].[ext]",
      esModule: false,
    }
  }
};
...

This saved my day and night too! Thank you very much 💯

@alessiocancian
Copy link

Fixed it with the following webpack config (esModule parameter):

...
const imageLoaderConfiguration = {
  test: /\.(gif|jpe?g|png|svg)$/,
  use: {
    loader: "url-loader",
    options: {
      name: "[name].[ext]",
      esModule: false,
    }
  }
};
...

I had a similar configuration but without esModule: false, adding that line did the trick

@gfaraj
Copy link

gfaraj commented Apr 18, 2021

I am having issues with images as well. Adding esModule: false definitely made some images show up for me now. But I haven't figured out why the icons on the bottom tab navigation container don't show up. Any ideas?

`

const Tab = createBottomTabNavigator();

export const HomeScreen = () => {
    useEffect(() => {
        trackScreen('Games');
    }, []);
    
    return (
        <Tab.Navigator
            screenOptions={({ route }) => ({
                tabBarIcon: ({ focused }) => {
                    let icon;
        
                    if (route.name === 'Games') {
                        icon = focused ? require('./img/nav/gamesIconColored.png') : require('./img/nav/gamesIcon.png');
                    } else if (route.name === 'Activity') {
                        icon = focused ? require('./img/nav/activityIconColored.png') : require('./img/nav/activityIcon.png');
                    } else if (route.name === 'Leaderboard') {
                        icon = focused ? require('./img/nav/leaderboardIconColored.png') : require('./img/nav/leaderboardIcon.png');
                    } else if (route.name === 'Prizes') {
                        icon = focused ? require('./img/nav/storeIconColored.png') : require('./img/nav/storeIcon.png');
                    } else if (route.name === 'Profile') {
                        icon = focused ? require('./img/nav/accountCircleColored.png') : require('./img/nav/accountCircle.png');
                    }
        
                    return <Image source={icon} width={wp(3)} height={wp(3)}/>;
                },
            })} 
            tabBarOptions={{
                showLabel: false,
                activeTintColor: 'rgb(153, 25, 255)',
                inactiveTintColor: 'rgb(80, 94, 118)',
            }}>
            <Tab.Screen name="Games" component={GamesScreen} />
            <Tab.Screen name="Activity" component={ActivityScreen} />
            <Tab.Screen name="Leaderboard" component={LeaderboardScreen} />
            <Tab.Screen name="Prizes" component={PrizesScreen} />
            <Tab.Screen name="Profile" component={ProfileScreen} />
        </Tab.Navigator>
    );
};

`

@RameshSain
Copy link

RameshSain commented Aug 2, 2021

Don't do any thing just dont use 'require' here
use

import logo from './logo.png';

@jkoutavas
Copy link

jkoutavas commented Aug 2, 2021

Don't do any thing just dont use 'require' here
use

import logo from './logo.png';

This has been working...

      <Image
        source={require('./assets/images/reddog.png')}
        style={styles.image}
      />

If I use import image from './assets/images/reddog.png', I get this ts2307 error:

Cannot find module './assets/images/reddog.png' or its corresponding type declarations.ts(2307)

Do I need to configure pathing for image imports? I can actually see the image displayed, after now removing the esModule: false from the webpack config.

I'm on React Native 0.64.2 and React Native Web 0.17.1 You can see my example project here: https://github.com/jkoutavas/add-rnw-to-rn-typescript-app. The README covers what I've done to incorporate image loading, specifically the section "A webpack tweak for image loading"

@u-r-w
Copy link

u-r-w commented Aug 8, 2021

Don't do any thing just dont use 'require' here
use
import logo from './logo.png';

This has been working...

      <Image
        source={require('./assets/images/reddog.png')}
        style={styles.image}
      />

If I use import image from './assets/images/reddog.png', I get this ts2307 error:

Cannot find module './assets/images/reddog.png' or its corresponding type declarations.ts(2307)

Do I need to configure pathing for image imports? I can actually see the image displayed, after now removing the esModule: false from the webpack config.

I'm on React Native 0.64.2 and React Native Web 0.17.1 You can see my example project here: https://github.com/jkoutavas/add-rnw-to-rn-typescript-app. The README covers what I've done to incorporate image loading, specifically the section "A webpack tweak for image loading"

I use webpack.config.js and all the config from rnw-to-rn-typescript-app; and apparently the image still need to be inlined styled like, for example
<Image source={props.logo} style={{ resizeMode: 'cover', width: '80%', height: '80%' }}/>

@gavrilikhin-d
Copy link

gavrilikhin-d commented Feb 13, 2024

Fixed it with the following webpack config (esModule parameter):

...
const imageLoaderConfiguration = {
  test: /\.(gif|jpe?g|png|svg)$/,
  use: {
    loader: "url-loader",
    options: {
      name: "[name].[ext]",
      esModule: false,
    }
  }
};
...

Be sure to turn off webpack-dev-server and start it again! It didn't work for me using hot reload, until I've completly restarted webpack server

@hamid842
Copy link

Thanks guys;
esModule: false,

solved my problem

@Alexa-Green
Copy link

This had fixed it at one point for me, but when introducing a turborepo setup any assets in the react-native package are now trying to load on the page itself (e.g. a Next GET request for the BACKGROUND_IMAGE_NAME.jpg):

Directory structure:

packages/
    ui/
        /src
            /assets
                BACKGROUND_IMAGE.jpg
            /components
                UserProfile.tsx // RN component which has `<ImageBackground` which has its source as `require('../assets/BACKGROUND_IMAGE')`
           ...rest of react components library here
    webapp/
        app/
            users/
                [userId]/
                    page.tsx // page which renders a `/webapp/components/RNUserProfile` which is a wrapper (use client) for a `UserProfile` component exported from `packages/ui`
         ...rest of nextjs project here

Am using these rules, but when it loads that image, it is trying to GET /users/BACKGROUND_IMAGE-hash.jpg from within next, rather than loading it from the file that I have confirmed sitting in packages/ui/dist.

Also need to support default nextjs image loading for images in the webapp/public folder.

// Find the rule that processes static images
    const fileLoaderRule = config.module.rules.find(rule =>
      rule.test?.test?.('.svg'),
    );

    // Exclude the rn directory from static image handling
    fileLoaderRule.exclude = [path.resolve(__dirname, '../packages/ui')];

    // Add a new rule for images in the rn directory
    config.module.rules.push({
      test: /packages\/ui\/.+\.(gif|jpg|jpe?g|png|svg)$/,
      use: {
        loader: 'url-loader',
        options: {
          name: '[name].[ext]',
          esModule: false,
        },
      },
    });

Any ideas?

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