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.
| Part | Example | Notes |
|---|---|---|
| Scheme | data: | Always first |
| Media type | image/svg+xml | Optional; defaults to text/plain;charset=US-ASCII |
| Parameters | ;charset=utf-8 | Optional, after the media type |
| Encoding flag | ;base64 | Present only when the data is base64 |
| Separator | , | Required, even with no media type |
| Data | PHN2Zz4uLi48L3N2Zz4= | 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.
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%3EPercent-encoded URL 48 characters
Rendered in a sandboxed frame
Paste a data URL
Media type: text/html;charset=utf-8
Encoding: base64
Decoded size: 11 bytes
Decoded text: <h1>Hi</h1>
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>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">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);
});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
}
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.
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.
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.
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.
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.
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.
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.
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.
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.