Webpacker: Images not loading - solidus (spree fork), react and webpacker

Created on 5 Nov 2019  路  2Comments  路  Source: rails/webpacker

I'm having an issue with images not loading in my configuration of solidus (a fork of Spree) - Rails 5.1.4, solidus 2.4.2, webpacker 4.0.2. I've implemented a react front end with react-rails 2.5.0

My (current) development.js for development webpack config:

process.env.NODE_ENV = process.env.NODE_ENV || "development";

const environment = require("./environment");

const config = {
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: "babel-loader",
        exclude: /node_modules/
      },
      {
        test: /\.(png|jpe?g|gif|svg)$/,
        use: [
          {
            loader: "file-loader",
            options: {
              limit: false,
              name: "./packs/images/[name].[ext]",
              outputPath: "images"
            }
          }
        ]
      }
    ]
  },
  devServer: {
    historyApiFallback: true,
    noInfo: true
  },
  performance: {
    hints: false
  },
  devtool: "#eval-source-map"
};

environment.config.merge(config);

module.exports = environment.toWebpackConfig();

Here is my _products.html.erb - On this page the image is being loaded from the erb, but has to have media instead of images prefixed. It is also loading the actual react code for the component, but not the images.

<%= react_component("index.ProductCard", { product: @products.first, image: @products.first.display_image }) %>
<%= image_tag asset_pack_path 'media/images/genericShirt.jpeg' %>

and my ProductCard.js:

import React, { FC, useState } from "react";

import Backdrop from '@material-ui/core/Backdrop';
import Fade from '@material-ui/core/Fade';
import Modal from '@material-ui/core/Modal';

import { Card, CardActionArea, CardContent, CardMedia, Typography } from '@material-ui/core';

import * as styles from './ProductShow.style'

import generic from "../../../images/genericShirt.jpeg"

interface Props {
  product: Product;
  image: Image;
}

interface Image {
  id: string;
  attachment_file_name: string;
}

interface Product {
  id: string;
  name: string;
  description: string;
  price: number;
  available_on: string;
  deleted_at: string;
  slug: string;
  meta_description: string;
  meta_keywords: string;
  tax_category_id: number;
  shipping_category_id: number;
  created_at: string;
  updated_at: string;
  promotionable: string;
  meta_title: string;
  origin_store: string;
  origin_country: string;
}

const ProductShow: FC<Props> = ({ product }) => {
  const [open, setOpen] = useState(false);

  const handleOpen = () => {
    setOpen(true);
  };

  const handleClose = () => {
    setOpen(false);
  };

  return (
    <div>
      <CardActionArea onClick={handleOpen}>
        <CardMedia
          title={product.name}
          image={generic}
        />
        <CardContent>
          <Typography variant="body2" color="textSecondary" component="p">
            {product.name}
          </Typography>
          <Typography variant="body2" color="textSecondary" component="p">
            PRODUCT PRICE
            {product.price}
          </Typography>

          <Typography variant="body2" color="textSecondary" component="p">
            PRODUCT IMAGE
              <img src={"../../../images/genericShirt.jpeg"} />
          </Typography>
        </CardContent>
      </CardActionArea>

      <Modal
        aria-labelledby="transition-modal-title"
        aria-describedby="transition-modal-description"
        css={styles.modal}
        open={open}
        onClose={handleClose}
        closeAfterTransition={true}
        BackdropComponent={Backdrop}
        BackdropProps={{
          timeout: 500,
        }}
      >
        <Fade in={open}>
          {/* <div css={styles.paper}>
            <h2 id="transition-modal-title">Transition modal</h2>
            <p id="transition-modal-description">react-transiton-group animates me.</p>
          </div> */}
          <Card>
            <Typography variant="body2" color="textSecondary" component="p">
              {product.name}
            </Typography>
          </Card>
        </Fade>
      </Modal>
    </div>
  );
}

export { ProductShow };

I also have in my application.js the line:

require.context("../images", true, /\.(png|jp(e*)g|gif|svg)$/);

The image tags with react are not populating. I have tried various methods to get this to work. Components and CSS is loading fine, just the images. I have tried many different configurations with webpack and my files with no luck so far, so any insight at all is really appreciated.

Most helpful comment

Looks like you need to use the imported image module in the src attribute, not the path.

Instead of:

<img src={"../../../images/genericShirt.jpeg"} />

Use

import genericShirtImage from "../../../images/genericShirt.jpeg";

// ...
<img src={genericShirtImage} />

All 2 comments

Looks like you need to use the imported image module in the src attribute, not the path.

Instead of:

<img src={"../../../images/genericShirt.jpeg"} />

Use

import genericShirtImage from "../../../images/genericShirt.jpeg";

// ...
<img src={genericShirtImage} />

Oh my god that worked thank you. I should have noticed that a while ago. Another set of eyes!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

christianrojas picture christianrojas  路  3Comments

itay-grudev picture itay-grudev  路  3Comments

towry picture towry  路  3Comments

vtno picture vtno  路  3Comments

iChip picture iChip  路  3Comments