How to handle images in a Rails / Webpacker / React app?

12,201

Solution 1

Just edit the file config/webpacker.yml and replace this line:

resolved_paths: []

with this this:

resolved_paths: ['app/assets']

Then, put the image in app/assets/images folder and load it like this:

import React from 'react'
import MyImage from 'images/my_image.svg'

const MyComponent = props => <img src={MyImage} />

export default MyComponent

Solution 2

If we leave resolved_path as [] in webpacker.yml also it works.

Example = 

# Additional paths webpack should lookup modules
  # ['app/assets', 'engine/foo/app/assets']
  resolved_paths: []

  static_assets_extensions:
    - .jpg
    - .jpeg
    - .png
    - .gif
    - .tiff
    - .ico
    - .svg
    - .eot
    - .otf
    - .ttf
    - .woff
    - .woff2

You can even create an image folder in your components. Load it in the component file like below-

import React from 'react;
import MyImage from '${imagePath}/example1.png'

export class MyComponent extends React.Component {
  render() {
  return (
  <React.Fragment>
   <img src={MyImage} alt="Image text"/>
  </React.Fragemnt>
  )
 }
}

Webpacker converts these image paths to packs.

Solution 3

Update 2021 (rails 6.1.4), the resolved_paths key has changed into additional_paths.

So, change :

# config/webpacker.yml

default: &default
  resolved_paths: []

into:

# config/webpacker.yml

default: &default
  additional_paths: ['app/assets']

and the rest following Daniel's answer's

Share:
12,201

Related videos on Youtube

adesurirey
Author by

adesurirey

Fullstack developer running on ruby, javascript, rails and react.

Updated on July 09, 2022

Comments

  • adesurirey
    adesurirey almost 2 years

    I am using Webpacker with rails 5.1.4 to play with React, Redux, and react-router-dom.

    I have a Navbar.jsx component in app/javascript/src/components/ that needs to display an image, but I am not able to access my images stored in app/assets/images/.

    Here is what I've tried :

    <img src="logo.png" alt="Logo" />
    <img src="assets/logo.png" alt="Logo" />
    <img src="assets/images/logo.png" alt="Logo" />
    

    From root path the last attempt works because /assets/images/logo.png does exist, but when I navigate to /posts/:id, it gives me the following error:

    logo.png:1 GET http://localhost:3000/posts/assets/images/logo.png 404 (Not Found)
    

    Can you help me? And more over what's your way to handle images in that kind or hybrid React/Rails app?

    Thanks

  • adesurirey
    adesurirey over 6 years
    Thanks a lot, you made my day. This was even more simple than said in the article you shared. All I had to do is install file-loader with yarn install file-loader then require my images import Logo from '../../../assets/images/logo.png'; and user it <img src={Logo} alt="Logo" />. that's great.
  • Logic Artist
    Logic Artist about 6 years
    I have exactly the same scenario, and I have tried the above, however I continue to get the error that the image cannot be resolved.
  • Manish
    Manish almost 6 years
    install has been replaced with add to add new dependencies. Run "yarn add file-loader" instead.
  • Fabrizio Bertoglio
    Fabrizio Bertoglio over 5 years
    I was able to implement this solution without adding app/assets to the resolved_paths
  • wuliwong
    wuliwong about 5 years
    What is line 11? Could you update this to show the entire file?
  • David Hersey
    David Hersey about 4 years
    This worked for me with Rails 6 ... unlike responses below I needed to add 'app/assets' to resolve_paths. I imagine I'd have to do this for CSS as well if I wanted to use assets folder for that.
  • Edward
    Edward almost 4 years
    If you use this method and also call the image from image_tag in your view, then your image is loaded twice
  • dkimot
    dkimot about 3 years
    while this works it's bad practice to add to the window object in js. it makes unit testing more difficult, allows any script on the page to change your image which could open up xss vectors, and you would have to follow that process for every image you want.