English

Developer tools · Base64 encoder & decoder

Data URIs explained: how data:image/png;base64 works and where it came from

· Background

base64 encoding

Data URI anatomy: scheme, media type, base64 flag, and Base64 payload
Original ToolAcre vector illustration

The data: URL scheme was specified in 1998 as a way to embed small resources directly in a page. This post explains its grammar, why Base64 is optional and where browsers draw limits.

The favicon that was a 1,300-character URL — meeting a data: URI in the wild and reading its parts

A data: URI embeds a small resource directly in a URL, avoiding a separate HTTP request. The format is specified in RFC 2397 (defined in 1998) and uses a grammar with a scheme, optional media type, optional encoding flag, and the payload itself. For example, data:text/plain,hello is a plain-text data URI containing the word hello. The browser processes this the same way it processes an HTTP request, but instead of fetching the content over the network, it decodes it from the URL itself.

Data URIs are most common for small images, CSS icons, and test fixtures. A data: URI with Base64 encoding looks like this: data:image/png;base64,iVBORw0K.... The breakdown is: data: is the scheme; image/png is the media type; ;base64 is the encoding flag; the long string is the Base64-encoded image bytes. When a browser sees this URL, it decodes the Base64 to recover the original bytes, then renders the image using those bytes.

Reading a data URI from its visible grammar — media type, optional Base64 marker and payload

If the encoding flag is omitted (data:text/html,<p>hello</p>), the payload is percent-encoded UTF-8 text, not base64. The presence of ;base64 tells the browser which decoding rule to apply. The media type in a data: URI is a MIME type, the same type string used in HTTP Content-Type headers. image/png, text/plain, application/json and image/svg+xml are common examples. If no media type is specified, the default is text/plain;charset=US-ASCII.

A browser must determine how to render the bytes based on the media type: if it says image/png, the bytes are PNG; if it says text/html, the content is HTML. Specifying the wrong media type can produce confusing results; a PNG file labeled as text/plain will display as garbage characters instead of an image. Base64 is optional in a data: URI. For text content, percent-encoding (the same encoding used in URL query strings) is often more compact than base64. A data URI consumer decides how to interpret the payload from the media type and the marker before the comma. The Base64 encoder supplies only the payload characters. It does not add a MIME type, choose whether the bytes describe PNG or SVG, or validate the assembled address.

Why Base64 is optional — percent-encoded text payloads for SVG and plain text versus Base64 for binary

The URI data:text/html,<p>Hello</p> contains the HTML as literal characters (with percent-encoding for any special characters like quotes or angle brackets). Base64 is useful for binary data that cannot be represented as text, and for cases where the payload contains many special characters that percent-encoding would bloat. A small SVG or a text file may be smaller percent-encoded; a binary file must be base64. Building a data: URI by hand requires knowing the media type and the encoding.

For an SVG icon, you can use data:image/svg+xml followed by either percent-encoded SVG markup or ;base64 and base64-encoded bytes. For percent-encoding, wrap the SVG in data:image/svg+xml, then percent-encode any angle brackets, quotes and other special characters. The result is long but human-readable. For base64, take the SVG bytes, encode them to base64, and produce data:image/svg+xml;base64, then append the base64 string. Base64 is usually more compact for binary, but for SVG text, the percent-encoded form may be shorter.

Worked example: building a data: URI for a small SVG by hand — encoding the markup as text and assembling the string

Browsers and consuming applications can impose limits or policy restrictions on data URIs, but this repository does not establish a portable numeric ceiling. Memory use, parser behavior and security policy also depend on where the value appears, so test the exact target browser and embedding context instead of relying on a remembered limit.

A 5 MB embedded image in every HTML file would bloat the page size. Data URIs are best for small resources: CSS icons, small images, or test data. For large files, an external request is faster because the browser can cache the response and reuse it across multiple pages; a data: URI is inlined every time the page loads.

Browser and security boundaries to verify in the consuming application rather than assume

A common threshold is a few kilobytes; below that, data: URIs are efficient; above that, external files are usually faster. Security and browser policies restrict data: URI usage in certain contexts. A top-level navigation (clicking a link that points to a data: URI with HTML content) is often blocked to prevent phishing. A data: URI in a script src attribute can execute arbitrary JavaScript, creating a security risk.

Browsers apply Content Security Policy (CSP) rules to data: URIs; a strict CSP may forbid them entirely. A data: URI in an img src or an iframe src is usually allowed, but embedded in a style or script context may be restricted. Always check the browser compatibility and security policy of your target environment. Data URIs in CSS are common for small background images. The syntax is the same: url(data:image/png;base64,...).

Where data: URIs are still the right tool — CSS icons, email-safe inline images and test fixtures

A CSS file with embedded data: URIs can be shipped as a single file with all images included, reducing HTTP requests. This is useful for small icon sets or simple graphics. Large images embedded in CSS bloat the file and slow down its parsing. Modern build tools (like webpack) can automatically convert small images to data: URIs in CSS, and external images to normal URLs, balancing performance.

The data: URI format is defined by RFC 2397, a short document that specifies the grammar but does not define where data: URIs can or cannot be used. Browser vendors have added their own restrictions based on security and performance concerns.

What this does not cover — blob: URLs, object URLs and file-system access

Some systems have deprecated data: URI support in certain contexts (like form-action in CSP level 3) to prevent abuse. When using a data: URI, test it in your target browser; the RFC says the format is valid, but the browser's security policy may block it.

Creating a data: URI manually is uncommon in production; most build tools and libraries handle the conversion. But understanding the format is useful for debugging. If you see a long data:image/... URL in your CSS or HTML, you can decode it with the Base64 encoder & decoder tool: remove the data:image/...;base64, prefix, paste the remaining string into the tool, and decode it to see the actual bytes.

Takeaway: a small format with strict grammar — how the Base64 encoder & decoder handles the text-encoding step so you can assemble a valid URI

For SVG data: URIs, you can percent-decode the text form and read the XML markup. Understanding the anatomy of a data: URI makes it easier to troubleshoot embedded resources. Data URIs are a Web standard (RFC 2397) that allows embedding resources directly as URLs. They are most efficient for small, stable resources that do not benefit from separate caching. The format includes optional media-type specification and an encoding flag (base64 or implied percent-encoding).

Base64 encoding is required for binary data but optional for text; percent-encoded SVG can be more readable. Browser security policies limit where data: URIs can be used, so understanding the restrictions in your target environment is essential. The Base64 encoder & decoder tool can help you manually encode a resource or decode an embedded URI to inspect its content.