Embed Images in a Single HTML File

You need one .html file that still shows its images — offline on a USB stick, forwarded as an email attachment, pasted into a CMS field that refuses uploads, or opened in an air-gapped browser. External src="https://…" links fail the moment the file leaves the network that hosted those assets. The fix is not another CDN. The fix is to put the image bytes inside the HTML as Base64 data URIs.

Encode the image locally with the Image to Base64 converter, paste the string into the template below, and ship a single file.

When a single file is the real constraint

People reach for Base64 HTML when the workflow forbids a second file:

If you can host images on HTTPS and control the page for months, keep normal files. Single-file Base64 is for the cases where the delivery unit must be one document.

How Base64 removes the asset dependency

A data URI is a URL that is the file:

<img src="data:image/png;base64,iVBORw0KGgo..." alt="Logo">

The browser does not fetch anything. The MIME type and the Base64 payload travel with the HTML. Relative paths like ./logo.png die as soon as you move the HTML alone; a data URI does not.

Trade-off: Base64 expands payload by about 33%, and inlined images cannot be cached separately. Keep icons, logos, and small diagrams inline; leave large photos as external files when the environment allows.

Step-by-step — encode, paste, ship one file

  1. Shrink first if needed. Large PNGs blow up HTML fast. Run them through Compress PNG to Base64 or check size with the Base64 image size calculator before you commit.
  2. Encode in the browser. Open Image to Base64 (or the Data URI Generator), drop the file, and copy the full data URI — the string that starts with data:image/…;base64,.
  3. Paste into src or CSS url(). Use the template in the next section. Do not wrap the data URI in quotes incorrectly, and do not prefix it with http://.
  4. Ship the one file. Open it from disk, attach it, or paste the HTML. No images/ folder travels with it.

For a site favicon that should also live inside the same file, generate the <link rel="icon"> tag with Base64 Favicon.

Copy-paste template (img + CSS background)

Replace PASTE_DATA_URI_HERE with the full data URI from the converter. The 1×1 PNG below is only a structural placeholder so the template validates before you swap real assets.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Self-contained report</title>
  <style>
    body { font-family: system-ui, sans-serif; margin: 2rem; color: #111; }
    .hero {
      width: 320px;
      height: 120px;
      background-image: url("PASTE_DATA_URI_HERE");
      background-size: contain;
      background-repeat: no-repeat;
      border: 1px solid #ddd;
    }
    .logo { max-width: 160px; height: auto; }
  </style>
  <!-- Optional inline favicon: paste from /base64-favicon -->
  <!-- <link rel="icon" href="data:image/png;base64,..." type="image/png"> -->
</head>
<body>
  <h1>Quarterly snapshot</h1>
  <p>This file has no external image requests.</p>

  <!-- Inline image -->
  <img
    class="logo"
    src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="
    alt="1x1 placeholder — replace with your data URI">

  <!-- CSS background using the same pattern -->
  <div class="hero" role="img" aria-label="Chart"></div>

  <p>Generated for offline delivery. Encode real assets at
     https://image2base64.com/</p>
</body>
</html>

Need to pull a data URI back out of an existing stylesheet later? Use Extract Base64 image from CSS.

Size, caching, and when not to inline

When to inline vs host
SituationPrefer
Logo ≤ ~20–40 KB after encodeInline data URI
Full-bleed photo / screenshot galleryHosted HTTPS files
Markdown README on GitHubRelative path — GitHub strips data: URIs; see Embed Base64 image in Markdown
API JSON payloadRaw or prefixed Base64 per API docs — Image to Base64 for API

If the HTML must stay under a mail-gateway size limit, compress first and favor SVG/PNG icons over camera JPEGs.

Troubleshooting

Image shows as a broken icon. The data URI was truncated on copy, the data: prefix was dropped, or a line break was inserted mid-string. Re-copy from the converter in one shot.

Works in the browser preview, fails after CMS save. Some editors sanitize data: URLs. Confirm the field allows them; if not, the constraint has moved — you need a host that permits uploads, not a bigger Base64 string.

File opens fine locally but looks empty in email. Many clients block or strip CSS backgrounds and sometimes <img data:>. Treat email as a separate constraint — see the Outlook and Gmail signature pages on this site.

Frequently asked questions

Does a single-file HTML with Base64 images work offline?

Yes. Once the data URIs are in the file, no network is required to render those images.

Is Base64 secure?

Encoding is not encryption. Anyone with the HTML can decode the image. Do not inline secrets.

Should every image be inlined?

No. Inline the assets that must travel with the document; leave heavy, cacheable media external when you can.

How do I encode an image for a single HTML file?

Open the Image to Base64 converter, drop the file, and copy the full data URI. Paste it into an img src or a CSS url().

Related tools