I'm rendering images in my UI using Base64-encoded JPEG URLs. While some images display correctly, others break the UI and only show the alt
text. I expect the fallback UI ("No Image"
div) to render instead when the image is invalid.
{property.propertyContent[0].imageUrls.length > 0 ? (
<img
src={property.propertyContent[0].imageUrls}
alt={property.title}
className="object-cover w-full h-full"
/>
) : (
<div className="flex items-center justify-center w-full h-full bg-gray-200">
<span className="text-gray-500">No Image</span>
</div>
)}
This works only if:
imageUrls.length > 0
However, when imageUrls
has a broken or invalid Base64 string (but still has length > 0), the image tag renders but fails to load — and the fallback div
is never shown.
I want to gracefully fallback to "No Image"
when:
length > 0
If the Base64 image fails to load for any reason (malformed or corrupted), I want to hide the image and show a fallback div like this:
<div class="bg-gray-200">No Image</div>
onError
fallback without bloating the codebase or using a fallback <img src>
?If you don’t want to use state, you can just hide the element inside the handler and keep the placeholder in the DOM:
<img
src={url}
alt={title}
className="object-cover w-full h-full"
onError={e => (e.currentTarget.style.display = 'none')}
/>
<div className="flex items-center justify-center w-full h-full bg-gray-200">
No Image
</div>
You can’t detect a corrupt image with a ternary on length; you have to wait for the load attempt and react to onError.
If you don't want image fallback, you need to use state:
function PropertyImage({ url, title }) {
const [broken, setBroken] = React.useState(false);
React.useEffect(() => setBroken(false), [url]); // reset when URL changes
return broken || !url ? (
<div className="flex items-center justify-center w-full h-full bg-gray-200">
<span className="text-gray-500">No Image</span>
</div>
) : (
<img
src={url}
alt={title}
className="object-cover w-full h-full"
onError={() => setBroken(true)}
/>
);
}
I think this is the only way.