Fallbacks for HTTP 404 images in HTML and JavaScript
Tags: webdev, tutorial, html, javascript
Published: 2023-12-18 09:24:40

Your images are 404ing all over the place. You’ve got an angry email from a client. Their site is “broken”, images aren’t loading, cumulative layout shift is running riot, and everything is messed up. The crowds are mocking your broken code on Twitter. A fun GIF loaded via a Giphy URL no longer exists. And someone has accidentally deleted an image from the CMS.

Now, whilst you can’t control third-party URLs or user errors in a CMS, you can prevent all of this from happening by providing fallbacks for image 404s in three different ways. Let’s take a look.

## Image fallbacks in HTML

The first way is the HTML-only way: no JavaScript required. [The HTML `<object>` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object) is often overlooked amidst the fancy framework-based image components available in the frontend ecosystem today and is used to represent an external resource, which can be an image, a video, or a web page. Historically, it was used to embed and run plugins on a webpage to display Flash movies, run ActiveX controls, Java applets, and other kinds of old-school web things. Today, it’s a pretty perfect use case for handling third-party image URLs that you have no control over. Plus, it has full browser support.

To use the HTML `<object>` element to provide a fallback image, assign the data attribute of the `<object>` element to the desired resource URL, and provide an HTML `<img>` element as a child of the `<object>`, pointing to the URL of a suitable fallback image. For accessibility reasons, provide an `aria-label` attribute on the `<object>` to describe the desired image (in place of an `alt` attribute). Additionally, ensure you specify the width and height of the image on both element tags to avoid cumulative layout shift as the page loads the resources and builds the page.

```html
<object
  type="image/png"
  data="https://somedomain.com/image.png"
  width="150"
  height="150"
  aria-label="This image should exist, but alas it does not"
>
  <img src="/path/to/fallback.png" alt="Fallback image" width="150" height="150" />
</object>
```

## Image fallbacks using JavaScript

Another way to provide an image fallback is to hook into the [HTMLElement onerror event](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/error_event). This fires on an element when a resource fails to load, or can’t be used. You can specify a new image source in the event of an error using the `onerror` attribute directly on the HTML `<img>` element.

```html
<img
  src="https://somedomain.com/image.png"
  alt="This image should exist, but alas it does not"
  width="150"
  height="150"
  onerror="this.src='/path/to/fallback.png'"
/>
```

If you’re unable to edit the HTML directly (say if you’re using a framework-based image component), you can use plain JavaScript (or your flavor of choice) to listen for the `onerror` event for all rendered HTML `<img>` elements, like so.

```javascript
const images = document.querySelectorAll("img");

images.forEach((image) => {
  image.addEventListener("error", (event) => {
    image.src = "/path/to/fallback.png";
  });
});
```

## Providing image fallback URLs from the server

If you’re requesting images from a backend managed by you or your team, check the HTTP status code of the image resource before attempting to return the URL via the API. If image URLs return a 404, you can send a URL to a fallback image in the response instead, reducing the need for extra logic and workarounds on the client.

This method will vary depending on the programming language and framework, but there are some drawbacks to this method. If a request needs to return hundreds of image URLs (for example on e-commerce search pages), and you need to check the HTTP response code for each image resource before returning the response, this method might negatively impact your API response times. Lazar goes into detail on this in his latest post: [What’s the difference between API Latency and API Response Time?](https://blog.sentry.io/whats-the-difference-between-api-latency-and-api-response-time/)

## Know when images are broken

Whilst you can code around broken images in your frontend applications to provide a better visual end-user experience, it’s also useful to know which images are failing to load so you can switch out broken URLs for working ones.

[Sentry](https://sentry.io/welcome/) doesn’t provide this functionality out of the box, but if it’s a growing concern in your frontend web applications, you can add this small snippet of JavaScript to your frontend to create an issue in Sentry if an image fails to load. This listens to all error events that may occur in the HTML document, and if the error occurs on an <img> element, it captures a message in Sentry with the source URL of the element that failed to load.

```javascript
document.body.addEventListener(
  "error",
  (event) => {
    if (!event.target) return;
    if (event.target.tagName === "IMG") {
       Sentry.captureException(`Failed to load image: ${event.target.src}`, "warning");
    }
  },
  true,
);
```

With this code snippet on your pages, you’ll see an issue created in Sentry when images 404. Additionally, you can do this for other resources, such as CSS files. [Read about capturing resource 404s on the Sentry docs.](https://docs.sentry.io/platforms/javascript/troubleshooting/#capturing-resource-404s)

![Sentry issue view showing message captured, with the URL of the image 404 as part of the message.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p7mn09nxb0bbfrvnw4wm.png)

## Get notified when images are broken

If you, or a designated team member, would like to get notified of image load failures in your front-end applications, you can create a custom alert in Sentry based on the “Failed to load image” message captured above.

1. Navigate to alerts, and click on Create Alert.
1. The Errors > Issues type is preselected for you. Click on Set Conditions.
1. Add the filter for if “The event’s {attribute} value {match} {value}”.
1. Leave the “message” and “contain” dropdown values as is, and set the “value” field to the message you send to Sentry when an image fails to load: “Failed to load image”.
1. Next, choose your notification options, and set a name for this alert.
1.Click save, and you’re done.

[View the interactive example on Arcade.](https://app.arcade.software/share/QUBGFsfxdWARe0rrlPnc)

## Defensive coding FTW

Let’s be real. Broken images usually aren’t that much of a problem, and this solution might be overkill for you. But, by considering what might go wrong in your applications and coding defensively around those what-ifs, you can save some serious mental time and energy. This means more time and brain space to innovate, take a break, and find the perfect Giphy GIF that sums up your reaction to the latest weird trending news in tech.