A data URI lets you embed a resource directly inside HTML, CSS, or JSON instead of linking to a separate file — perfect for tiny icons, inline SVG, or short snippets. This tool builds and decodes data URIs in your browser.
How it works
A data URI has the form data:[mediatype][;base64],data:
- The text is converted to UTF-8 bytes.
- Base64 mode encodes those bytes with the standard alphabet and emits
data:<mime>;base64,<base64>. - Percent-encoding mode leaves unreserved ASCII bytes (
A-Z a-z 0-9 - . _ ~) as-is and writes every other byte as%XX, emittingdata:<mime>,<percent-encoded>.
Decoding parses the prefix to read the MIME type and detect the ;base64 flag, then reverses the matching transform to recover the original text.
Base64 vs percent-encoding: which to choose
Both modes produce a valid data URI, but they differ in size and readability:
Base64 works by encoding every 3 bytes of input as 4 ASCII characters. This adds approximately 33% overhead regardless of what the content is. The output is opaque — you cannot tell what the original data was by reading the Base64 string. Base64 is the right choice for binary data (PNG, WOFF fonts, PDF bytes) because binary is full of bytes that would need escaping in percent-encoding, making the alternative even larger.
Percent-encoding leaves safe ASCII characters as-is and escapes everything else as %XX. For content that is mostly printable ASCII — inline SVG, small JSON snippets, plain text — percent-encoding produces a shorter, human-readable output. An SVG file is almost entirely ASCII angle brackets, letters, and numbers, so percent-encoding it may produce a result 10–20% shorter than Base64 and one you can still read and debug.
Quick guide:
| Content type | Recommended encoding | Reason |
|---|---|---|
| PNG, JPEG, WOFF | Base64 | Binary — percent-encoding would be huge |
| Inline SVG | Percent-encoding | Mostly ASCII — shorter and readable |
| Plain text snippet | Percent-encoding | Readable and compact |
| JSON payload | Percent-encoding | Mostly ASCII characters |
MIME types to know
The MIME type is declared in the data URI prefix and tells the browser or consumer how to interpret the data:
| MIME type | Use |
|---|---|
text/plain | Plain text, default for simple strings |
image/svg+xml | Inline SVG in <img> src or CSS url() |
image/png | Inline PNG image |
application/json | JSON payload inlined in HTML or a script |
text/css | Inlined stylesheet (uncommon but valid) |
font/woff2 | Inlined web font (heavy — usually too large) |
If you omit the MIME type, the browser defaults to text/plain;charset=US-ASCII. Always specify the correct type explicitly.
Example: inline SVG in CSS
A common use case is inlining a small icon SVG in a CSS background-image, avoiding an extra HTTP request for a tiny file. For a simple circle SVG:
data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Ccircle cx='5' cy='5' r='5'/%3E%3C/svg%3E
The < and > characters become %3C and %3E. The result goes directly into the CSS url() value: background-image: url("data:image/svg+xml,...").
When not to use data URIs
Data URIs make sense for small, frequently-reused assets where the HTTP round-trip cost exceeds the encoding overhead. They are a poor choice for:
- Large images. A 200 KB PNG becomes roughly 267 KB in Base64 and bloats the HTML or CSS that includes it, slowing initial parse without the option for separate caching.
- Assets shared across pages. A separate file is cached by the browser once and reused across all pages. An inlined asset is re-parsed on every page load.
- Content that changes. Updating an inlined asset means touching every HTML file that contains it, rather than updating a single external file.
Reserve data URIs for tiny icons, loading spinners, fallback images, and one-off snippets where removing an HTTP request is genuinely worth the tradeoff. Everything encodes and decodes in your browser — nothing is uploaded.