A broken-image icon on a listing card is the visual equivalent of a 500 error — users interpret it as site neglect and scroll past the listing entirely, regardless of how good the underlying content is. Browse pages with scattered broken images look abandoned, review crawlers flag the domain for quality issues, and social previews (Open Graph, Twitter Card) fall back to site defaults instead of listing-specific imagery. A category-appropriate placeholder keeps the grid visually uniform and signals the listing is real, just not yet photographed.
Low because the underlying data is intact, but broken image icons make the entire browse grid look unmaintained.
Add a fallback placeholder image per category and render it whenever imageUrl is null or unreachable. Keep the placeholders in public/images/placeholders/ with one variant per top-level category so cards stay visually coherent. Wrap the <img> in a small ListingImage component that handles the null case and sets an onError handler to swap in the placeholder if the CDN URL later 404s.
export function ListingImage({ listing }: Props) {
const fallback = `/images/placeholders/${listing.category}.png`
return <img src={listing.imageUrl || fallback} alt={listing.name} loading="lazy" />
}
ID: directory-listing-schema.image-handling.placeholder-image
Severity: low
What to look for: Count all listings without images. For each, test creating a listing without uploading an image. Check if the listing detail page displays gracefully (with a placeholder image) or shows a broken image icon.
Pass criteria: Listings without images display a placeholder image or icon instead of a broken image — 100% of listings without images must display a category-appropriate placeholder. Report: "X listings without images found, all Y display appropriate placeholders."
Fail criteria: Listings without images show a broken image icon or empty space.
Skip (N/A) when: Images are required for all listings.
Detail on fail: Example: "Listings without images show broken image icon"
Remediation: Provide a fallback placeholder:
<img
src={listing.imageUrl || '/images/placeholder-listing.png'}
alt={listing.name}
/>