Data URLs: data:text/html;base64 and Friends, Explained

A data URL carries a whole file inside the address itself: data:, an optional media type, ;base64 if the bytes are base64 encoded, a comma, then the content. data:text/html;base64,PGgxPkhpPC9oMT4= is a tiny web page. Base64 makes the payload about a third larger, and browsers refuse to open data: pages as a top-level tab.

Anatomy of a data URL
PartExampleNotes
Schemedata:Always first
Media typeimage/svg+xmlOptional; defaults to text/plain;charset=US-ASCII
Parameters;charset=utf-8Optional, after the media type
Encoding flag;base64Present only when the data is base64
Separator,Required, even with no media type
DataPHN2Zz4uLi48L3N2Zz4=Base64, or percent-encoded text

Updated

Data URLs are handy for tiny icons, CSS backgrounds, test fixtures and generated downloads, and a common source of confusion when someone pastes a long data:text/html string into the address bar and nothing happens. Below you can encode any text into a data URL, decode one back, and see exactly what it costs in bytes compared with the original.

Data URL encoder and decoder

Content to encode: <h1>Hi</h1>

Media type: text/html;charset=utf-8

Base64 data URL

data:text/html;charset=utf-8;base64,PGgxPkhpPC9oMT4=

Original 11 bytes, base64 URL 52 characters

Percent-encoded data URL

data:text/html;charset=utf-8,%3Ch1%3EHi%3C/h1%3E

Percent-encoded URL 48 characters

Rendered in a sandboxed frame

Decode a data URL

Paste a data URL

Media type: text/html;charset=utf-8

Encoding: base64

Decoded size: 11 bytes

Decoded text: <h1>Hi</h1>

Data URLs in real code

SVG background in CSS, percent-encoded

Single quotes inside the SVG avoid clashing with the double quotes around url(), and the colour's # is written as %23.

<style>
  .dots { height: 80px; border-radius: 12px;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Ccircle cx='8' cy='8' r='3' fill='%234F98FB'/%3E%3C/svg%3E"); }
</style>
<div class="dots"></div>

A tiny inline image

The same idea works in an img tag. Keep alt text, as with any image.

<img alt="Blue square" width="48" height="48"
  src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 1'%3E%3Crect width='1' height='1' fill='%234F98FB'/%3E%3C/svg%3E">

Build a data URL from a file in JavaScript

FileReader.readAsDataURL produces the full data: string, media type included, for a file the visitor picks.

const input = document.querySelector('input[type="file"]');
input.addEventListener("change", () => {
  const file = input.files[0];
  if (!file) return;
  const reader = new FileReader();
  reader.addEventListener("load", () => {
    console.log(reader.result); // "data:image/png;base64,iVBORw0..."
  });
  reader.readAsDataURL(file);
});

Turn a data URL back into a Blob

fetch understands data: URLs, which is the shortest way to get the bytes back out.

async function dataUrlToBlob(dataUrl) {
  const res = await fetch(dataUrl);
  return res.blob(); // keeps the media type
}

When inlining helps and when it hurts

Inlining saves a request, which matters for a handful of tiny assets such as a loading spinner or a favicon in a single-file demo. It hurts when the asset is large or used on many pages, because the bytes ride along with every HTML file or stylesheet instead of being cached once.

A reasonable rule: inline things under a few kilobytes that appear once, and link everything else as a normal file.

Base64 or percent-encoding?

Binary files such as PNG, JPEG and fonts need base64. Text formats, especially SVG, can use percent-encoding: only characters like #, %, < and > and spaces need escaping, so the result is often shorter and still human readable.

The encoder below shows both lengths side by side so you can pick the smaller one for your own content.

Common mistakes

A typo in the base64, a stray line break or a wrong media type fails silently: the image simply does not show. Run a broken string through the decoder to see where it goes wrong.

Another frequent slip is forgetting the comma when there is no media type. data:,Hello is valid; data:Hello is not a usable data URL.

How it works

  1. Type or paste content and choose its media type. The tool shows both the base64 and the percent-encoded form, with their lengths.
  2. Compare the sizes. Base64 is close to four characters for every three bytes; percent-encoding can be shorter for plain text and SVG.
  3. Paste any data URL into the decoder to read its media type, encoding and contents. Image types show a preview.
  4. HTML results render in a sandboxed frame, because a data: page cannot be opened as a tab of its own.

Tips

Frequently asked questions

Why does data:text/html;base64 not open when I paste it in the address bar?

Modern browsers block top-level navigation to data: URLs as an anti-phishing measure, because a data page could imitate any site while hiding its real origin. The content still works inside an iframe, an img element or as a download link.

How much bigger does base64 make a file?

Roughly one third. Base64 writes every three bytes as four characters, so a 30 KB image becomes about 40 KB of text before any compression. The exact growth depends on the length and padding.

How do I turn a base64 data URL back into an image?

Paste it into the decoder on this page to preview it, or put it straight into an img src. To save it as a file, use our image to base64 tool in reverse, or fetch the data URL in JavaScript and save the resulting Blob.

Is there a size limit?

MDN lists 512 MB for Chromium and Firefox and 2,048 MB for Safari. Long before that, huge data URLs make HTML and CSS slow to parse and impossible to cache, so keep them to a few kilobytes.

What origin does a data URL page have?

An opaque origin of its own, not the origin of the page that created it. So script inside a data: iframe is treated as a stranger by the page that holds it, not as part of the same site.

Related: Image to base64 converter, Base64 encoder and decoder, URL encoder and decoder, iframe sandbox tokens, SVG optimizer.

Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.

More in Guides

We.Inc is an AI-powered website builder you can resell under your own brand. Launch a branded client dashboard, bill on Stripe Connect, and deliver AI-generated websites in minutes. White-label plans start at $99 a month for 25 client sites, with a 7-day free trial and no per-site fees.

Product

Who It's For

Features

Resources

Company

View Sitemap