How would you handle image failures in production?

JavaScriptLivspace

Handling Image Failures

When images fail to load in production, it's important to provide a good user experience by showing a fallback image. The most common way to handle this is by using the onerror event handler.

However, first we will understand how image looks when it fails to load. Then, we will implement a robust error handler.

Working Image Example

<img src="https://picsum.photos/200" />

Image Failure Example

When an image fails to load, you'll see a broken image icon like this:

Here we are passing invalid image URL to the src attribute, so it will fail to load. However, in production, the image could fail to load due to a variety of reasons such as network issues, invalid URL, etc.

Handling Image Failures

The <img /> element has an onerror event handler that can be used to handle image failures. This event is triggered in the below mentioned scenarios:

  • Empty or null src attribute
  • src URL matches current page URL
  • Corrupted image file
  • Corrupted image metadata, makes it impossible to retrieve dimensions
  • Unsupported image format

Here's how to implement a robust error handler using the onerror event

<img
src="https://picsum.photos"
width="200"
height="200"
alt="Random Image"
onerror="handleImageError(this)"
/>
window.handleImageError = function (image) {
// Clear the error handler to prevent infinite loops
// If we don't clear it and the fallback image also fails,
// it would trigger onerror again and again
image.onerror = "";

// Set a fallback image URL
// Make sure this URL is reliable and points to a default/placeholder image
// In production, this should be a static asset on your own server
image.src = "https://picsum.photos/200";

// Return true to indicate the error was handled
// This is a convention for event handlers
return true;
}

Working Example

Here's a working example of how to handle image failures using the onerror event. We have used the same broken image URL(https://picsum.photos) as before in the index.html file. However, when the image fails to load, the handleImageError function is called and the image is replaced with a fallback image.

Understanding the Infinite Loop Prevention:

  • Original image fails -> triggers onerror
  • Remove the onerror handler first
  • Then set the new src
  • If fallback fails, there's no handler anymore (we removed it)
  • No handler means no more attempts = no infinite loop

Interesting Fact

The <Image /> component in Next.js also has a similar feature to handle image failures. Internally it uses the onerror event to handle image failures. You can take a look at the implementation here:

https://github.com/vercel/next.js/blob/canary/packages/next/src/client/image-component.tsx#L294
00:00