src/images folder in create-react-app

16,700

Solution 1

What I normally do for assets under /public/assets i import my files then in my react components using src i can access them using process.env.PUBLIC_URL + '/assets/{ENTER REST OF PATH HERE}'

here is a code sample how I implement it.

import React, { Component } from 'react';

const iconPath = process.env.PUBLIC_URL + '/assets/icons/';

export default class TestComponent extends Component {
    constructor(props) {
        super(props);
    }
    render(){
    return (<img
        src={`${iconPath}icon-arrow.svg`}
        alt="more"
    />)
    }
}

Here is the link that got me started implementing it this way. https://github.com/facebook/create-react-app/issues/2854

I also noticed you are importing logo incorrectly and should be import logo from '../images/logo.svg' or if logo.svg does not have an export default you should be using import {logo} from '../images/logo.svg'

Solution 2

You can use ES6 import to locate any file (images, audio, etc) from the root folder and add them to your app.

import React from 'React'
import errorIcon from './assets/images/errorIcon.svg'
import errorSound from './assets/sounds/error.wav'

class TestComponent extends React.Component 
{ 
    render() 
    {
        return (

            <div>
                <img src={ errorIcon }
                     alt="error Icon" />

                <audio src={ errorSound } />
            </div>
        )
    }
}
Share:
16,700
Edvin Keskin
Author by

Edvin Keskin

Updated on June 12, 2022

Comments

  • Edvin Keskin
    Edvin Keskin almost 2 years

    I have an app scaffolded using create-react-app. I would like to have the folder structure like this:

    src/
      components/
        CustomAppBar.js
      images/
        logo.svg
      App.js
      index.tsx
    images.d.ts
    

    Currently I would like to use the logo.svg in the images folder in CustomAppBar.js. Currently this file looks like this:

    import React from 'react';
    import PropTypes from 'prop-types';
    import { withStyles } from '@material-ui/core/styles';
    import AppBar from '@material-ui/core/AppBar';
    import Toolbar from '@material-ui/core/Toolbar';
    import Typography from '@material-ui/core/Typography';
    import Button from '@material-ui/core/Button';
    import IconButton from '@material-ui/core/IconButton';
    import MenuIcon from '@material-ui/icons/Menu';
    import logo from '*.svg';
    
    const styles = {
      flex: {
        flex: 1,
      },
      menuButton: {
        marginLeft: -12,
        marginRight: 20,
      },
      root: {
        flexGrow: 1,
      },
    };
    
    function ButtonAppBar(props) {
      const { classes } = props;
      return (
        <div className={classes.root}>
          <AppBar position="static" title={<img styles={{height: '50px'}} src={logo} />}>
            <Toolbar>
              <IconButton className={classes.menuButton} color="inherit" aria-label="Menu">
                <MenuIcon />
              </IconButton>
              <Typography variant="title" color="inherit" className={classes.flex}>
                Title
              </Typography>
              <Button color="inherit">Login</Button>
            </Toolbar>
          </AppBar>
        </div>
      );
    }
    
    ButtonAppBar.propTypes = {
      classes: PropTypes.object.isRequired,
    };
    
    export default withStyles(styles)(ButtonAppBar);
    

    As expected, this fails with:

    Module not found: Can't resolve '*.svg' in 'some\path\src\components

    The content of images.d.ts is stock standard:

    declare module '*.svg'
    declare module '*.png'
    declare module '*.jpg'
    

    I have found a couple of suggestions elsewhere that mention modifying Webpack config. It seems create-react-app has hidden away Webpack config stuff. What's the best practice when it comes to this?

  • Edvin Keskin
    Edvin Keskin almost 6 years
    Thanks, that works for now... but I will wait and see if there are any cleaner solutions. I guess if not I can always wrap something like this in helper functions.
  • Joshua Fermin
    Joshua Fermin almost 6 years
    made a few updates to my answer hope that's a little cleaner.
  • Edvin Keskin
    Edvin Keskin almost 6 years
    I have tried the ../images/logo.svg import but that raised an error too.
  • Joshua Fermin
    Joshua Fermin almost 6 years
    if logo.svg does not have an export default you should be using import {logo} from '../images/logo.svg' if I could see the contents of logo.svg it would be very helpful.
  • Edvin Keskin
    Edvin Keskin almost 6 years
    Your last sentence was actually the answer. I have edited it to removed the use of PUBLIC_URL. Using the correct import will include the benefits of cache busting.
  • Akhila
    Akhila over 3 years
    What if I have multiple images and I'm importing an object array which has all the image paths? I can't do import for every other image right? @anonym
  • Akhila
    Akhila over 3 years
    Is there any other way other than using the public url or importing each an every image in the case of an array of images?