Images not showing in an HTML page: the 5 causes and the fix for each

Empty boxes where pictures should be. In almost every case the page is asking for a file that is not next to it. Open the Network panel, read the failed address, and it tells you which of five causes you have.

Images not showing in an HTML page is almost always one thing: the page is asking for a file that is not where it expects.

Images not showing: the page arrived, the pictures did not. They were referenced from a folder that stayed behind.
Images not showing: the page arrived, the pictures did not. They were referenced from a folder that stayed behind.

It works on your machine because the folder is there, and breaks for everyone else because they got the HTML alone. There are five causes, they look identical on screen, and the Network panel tells them apart in ten seconds.

This guide covers the five, the check, and the two ways to make images travel with the page.

The five causes

1. A folder path that did not travel

<img src="images/chart.png">

This means "a folder called images, right next to this file". It is correct on your machine and meaningless anywhere else. Sending the HTML alone sends a page full of instructions to look at files that are not there. This is the cause nine times out of ten, and relative versus absolute paths explains the rule.

ON YOUR MACHINE report.html says: src="logo.png" finds it logo.png sitting in the same folder AFTER YOU SEND IT report.html still says: src="logo.png" finds nothing empty box the folder did not travel
The same reference resolving on your machine and resolving to nothing afterwards.

2. An absolute disk path

<img src="C:/Users/you/Desktop/chart.png">

This works only on your account on your machine. Sometimes it is worse than nothing, because it reveals your folder structure to whoever reads the source. Editors and export tools write these more often than you would expect.

3. A name or case mismatch

Chart.PNG and chart.png are the same file on Windows and macOS by default, and two different files on the servers most pages end up on.

A page that works locally and breaks once served is very often this, and it is maddening precisely because nothing looks wrong. The same goes for .jpg in the tag and .jpeg on disk.

4. An http image on an https page

The browser blocks it as mixed content and shows nothing. There is no visible error unless you have the console open. Change the address to https://; if the host does not serve it that way, copy the image somewhere that does.

5. A frame that is not allowed to load outside resources

If the page is being rendered inside a restricted frame, a preview pane or an embed, outside requests may be blocked by design. The image is fine; the surroundings will not fetch it. Open the page directly and the image appears.

How to tell them apart in ten seconds

  1. Open the Network panel. Press F12, click Network, filter by Img, and reload the page.
  2. Read the failed address. Every image request is listed with its status and the full address the browser asked for. That address tells you which of the five you have:
The console shows each missing image as a 404 with the path the page asked for.
The console shows each missing image as a 404 with the path the page asked for.
What the address looks like Status Cause
file:///.../images/chart.png failed, file not found Folder path, file not there
file:///C:/Users/... failed Absolute disk path
Correct web address 404 Name or case mismatch
http://... on an https page blocked: mixed-content Mixed content
No request made at all Frame is blocking it
  1. Fix the reference using one of the two methods below.
  2. Check in a fresh window. Open the file in a viewer that has never seen your folder, such as the HTML file opener. Images that survive there will survive for the reader.

Making images travel with the page

Two options, different trade-offs.

An image embedded in the file as a data URI. It travels with the page and cannot go missing.
An image embedded in the file as a data URI. It travels with the page and cannot go missing.

Embed as a data URI

<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..." alt="Weekly signups">

The image is now inside the file. Nothing can separate them, and the page works with no network at all.

The cost is size: base64 encodes every three bytes as four characters, so the text is a third larger by definition, and everything is carried in one file. Compress the image before encoding.

A screenshot saved straight out of a phone is several megabytes and does not need to be; resized to the width it will be shown at and saved as WebP or a compressed PNG, it is a few tens of kilobytes.

See base64 images for how to produce the string.

Use a full address

<img src="https://example.com/img/chart.png" alt="Weekly signups">

Keeps the file small and works from anywhere with a network. The page now depends on that address continuing to serve the image, which is fine if you control it and a slow-acting time bomb if you do not.

A link to an image inside a chat app or a drive is not a stable address; it expires or requires a login.

Images from an export or an AI assistant

Two sources produce broken images more than any other. Report and dashboard tools export report.html plus a folder of assets, and only the .html gets sent.

And an AI assistant writing a page will invent an image address, a placeholder such as images/hero.png or a stock-photo link that does not exist, because it cannot supply the picture.

In both cases the fix is the same: replace the reference with an embedded image or a full address you control, and drop the placeholder if there is no real picture to put there. Fixing AI-generated HTML covers the other things assistants leave behind.

Use SVG where you can

For charts, diagrams, logos and icons, SVG beats both options.

It goes straight into the markup as text, so it is embedded by definition, it is usually smaller than the equivalent picture, it stays sharp at any zoom, and its colours can be driven by your CSS, including adapting to dark mode, which a fixed image cannot do.

Every diagram on this page is inline SVG for exactly those reasons.

Always write the alt text

<img src="..." alt="Weekly signups by source, search highest">

Two reasons, and the second is the one people forget. It is what screen readers read. And it is what shows instead of the image when the image fails to load, so a page with good alt text degrades into something still readable rather than into empty boxes.

When the page is served rather than sent

If the page lives at an address instead of being sent as a file, most of this disappears: images on full addresses are fetched normally, and nobody is holding a copy with a missing folder.

In NOS pasted HTML renders as written and the page is served rather than handed over, so an image on a full https:// address simply appears, for everyone, and an embedded one travels inside the document.

The check is the same either way: open the page in a fresh window before you send the link.

Questions people ask

Why do images show on my computer but not when I send the HTML file?

The image tags point at a folder next to the file, such as images/chart.png. On your machine that folder exists. The person you sent the file to received the HTML alone, so the browser asks for files that are not there. Embed the images or use full https addresses.

How do I find out why an image is not loading?

Press F12, open the Network tab, filter by Img and reload. Each image is listed with its status and the full address the browser asked for. A file:/// address means a folder path, a 404 means the name or case is wrong, a mixed-content block means an http image on an https page.

How do I make images part of the HTML file?

Encode each image as base64 and put it in the src attribute as a data URI. The image is then inside the file and cannot be separated from it. Compress the image first, because base64 makes it a third larger.

Does embedding make the file much bigger?

By about a third of the image sizes. A few compressed screenshots add a few hundred kilobytes. A phone photo saved straight in adds several megabytes each, so resize and compress before encoding.

Is a full https:// image address better than embedding?

It keeps the file small and works from anywhere with a network, as long as that address keeps serving the image. Use it for images you control; embed images that must survive without the network.

Keep reading