Changing the default/fallback image in a listing view

I'd like to override the default/fallback image in a listing view.
Like in this screenshot:

I tried creating a shadow component of PreviewImage.jsx but that doesn't seem to work.

customizations
│   ├── README.md
│   ├── collections
│   └── components
│       └── theme
│           ├── PreviewImage
│           │   ├── PreviewImage.jsx
│           │   └── default-image.svg

Here's my code:

import PropTypes from 'prop-types';

import config from '@plone/volto/registry';

import MyDefaultImageSVG from './default-image.svg';

/**
 * Renders a preview image for a catalog brain result item.
 */
function PreviewImage({ item, alt, image_field, showDefault = true, ...rest }) {
  const Image = config.getComponent({ name: 'Image' }).component;

  const image = (
    <Image
      item={item}
      image_field={image_field || item.image_field}
      alt={alt}
      {...rest}
    />
  );

  if (!image && !showDefault) return null;

  if (image_field || item?.image_field) {
    return image;
  } else {
    return (
      <img
        src={MyDefaultImageSVG}
        alt={alt}
        {...rest}
        width="400"
        height="300"
      />
    );
  }
}

PreviewImage.propTypes = {
  item: PropTypes.shape({
    '@id': PropTypes.string.isRequired,
    title: PropTypes.string.isRequired,
    image_field: PropTypes.string,
    image_scales: PropTypes.object,
    showDefault: PropTypes.bool,
  }),
  alt: PropTypes.string.isRequired,
};

export default PreviewImage;

I'm not sure why that didn't work -- maybe something about relative imports from a shadowed component.

I think you can shadow just the image file without shadowing PreviewImage.jsx, if you put it in the correct path: customizations/volto/components/manage/Blocks/Listing/default-image.svg

I tried both paths for good measure

  1. customizations/volto/components/manage/Blocks/Listing/default-image.svg
  2. customizations/components/manage/Blocks/Listing/default-image.svg

I believe #2 is the correct one.
Neither had any effect.

@davisagli,
btw.. is including volto in the path a recent thing?
The examples in the documentation don't mention this... (e.g. Footer – Volto Hands-On — Plone Training 2024 documentation which says to use the path customizations/components/theme/Footer/Footer.jsx

Unless I'm imagining... customizations/components/... was working for me.
Now I have to use customizations/volto/components/....

If you don't have any addons to shadow, you can use customizations/components, however, if you want to introduce shadows of addons, you need to be able to specify which addon you are shadowing and also you need to differentiate between the addon shadows and the Volto code you have already shadowed. So customizations/volto/components is then used.
I often jump straight to using customizations/volto to avoid any future work of moving things about as there's no downside really other than having one extra folder

1 Like

@JeffersonBledsoe okay... that makes sense, I feel like I have a better grasp of why that works now and why it might have stopped working.

1 Like

I'm yet to successfully override the default image.
Using either PreviewImage.jsx or default-image.svg.
Will return to this in the future.

I don't know if this is the problem, but keep in mind that if you add new override files, you have to completely restart the Volto process. The dev server watches for changes to existing files, but doesn't notice if new files are added.

Thanks @davisagli I'm pretty sure I did that. I'll continue to do further investigation.