A data URI is a URI using the data: scheme that embeds a small resource, such as an image or snippet of text, directly inside the URI itself instead of pointing to a separate file, so the data travels inline with the document that references it. Defined by RFC 2397, a data URI lets you place a file’s contents right where a URL would normally go, for example as the source of an image or a background in a stylesheet. This eliminates a separate network request for that resource, which is useful for tiny assets but comes with real trade-offs around size, caching, and security.
Key takeaways
- A data URI inlines a resource using the
data:scheme instead of linking to a separate file. - Its syntax is
data:[mediatype][;base64],[data]. - Binary content should be
;base64encoded; small text can be percent-encoded instead. - The default media type when omitted is
text/plain;charset=US-ASCII. - Data URIs are not cached independently and base64 inflates size by about a third, so they suit only small assets.
- They can carry executable content, so untrusted data URIs are a security concern best constrained with CSP.
What is the syntax of a data URI?
A data URI has four parts after the scheme: an optional media type, an optional base64 flag, a mandatory comma, and the data.
data:[<mediatype>][;base64],<data>
Here are concrete examples:
data:,Hello%2C%20World
data:text/plain;base64,SGVsbG8sIFdvcmxk
data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...
The first embeds percent-encoded plain text with no explicit media type. The second embeds the same text base64-encoded. The third embeds a PNG image as base64. Everything after the comma is the payload, interpreted according to the media type and whether the base64 flag is present.
What is the default media type?
If you omit the media type entirely, as in data:,Hello, the specification says the default is text/plain with a US-ASCII character set. You can override this by supplying a media type, and you can add parameters such as a charset, for example data:text/plain;charset=utf-8,.... Specifying the correct media type matters because it tells the consumer how to interpret the bytes, exactly as the Content-Type header would for a fetched resource.
When should I use base64 versus text encoding?
The payload can be represented two ways, and the right choice depends on whether the data is binary or textual.
| Encoding | Best for | Trade-off |
|---|---|---|
Base64 (;base64) |
Binary data: images, fonts, audio | Increases size by roughly one third |
| Percent-encoded text | Small text: SVG, plain text, simple markup | Only certain characters need escaping |
Binary data cannot be placed literally in a URI, so it must be base64 encoded. Text data, by contrast, can often be included directly with only reserved characters percent-encoded, which is more compact than base64 for short text. A frequent pattern is inlining small SVG icons as percent-encoded text rather than base64, since SVG is text and stays smaller.
Where are data URIs commonly used?
Data URIs show up wherever a small resource benefits from being embedded:
- Inline images: a tiny icon or placeholder embedded directly as an image source.
- CSS backgrounds: small background images or SVG shapes placed inline in a stylesheet.
- Embedded fonts: occasionally used to inline a font, though the size cost is high.
- Self-contained documents: bundling assets into a single file so it has no external dependencies.
The unifying motive is removing a separate network round trip, which can shave latency when a page needs a handful of very small assets.
Why are data URIs not cached separately?
This is the most important trade-off to understand. A normally linked file is fetched by its own URL, so the browser can cache it once and reuse it across many pages. A data URI has no independent URL; its bytes live inside the referencing document or stylesheet. As a result:
- The embedded resource is cached only as part of its host document, never on its own.
- If the same image is inlined on ten pages, its bytes are downloaded ten times rather than cached once.
- Changing the host document invalidates the inlined asset along with it.
For an asset reused across many pages, a normal cacheable URL is almost always better. Data URIs pay off only for tiny, page-specific assets where the saved request outweighs the lost caching.
What are the size and performance costs?
Base64 encoding represents three bytes of input using four characters of output, so the encoded form is roughly one third larger than the original binary. That inflation is added to the host document, which the browser must download and parse before it can use the inlined asset. Very long data URIs also stress parsers and can be awkward to work with in source files.
The practical guidance is qualitative: reserve data URIs for small assets, keep an eye on how much they bloat the host file, and prefer external, cacheable resources as assets grow larger or are shared across pages. There is no benefit to inlining large images this way.
What security considerations apply to data URIs?
Because a data URI can carry any media type, it can also carry active content such as HTML or scripts. That makes untrusted data URIs a potential vector for injecting executable content, particularly in contexts that navigate to or render the URI. To reduce risk:
- Never build a data URI that will be rendered as markup from untrusted input without careful sanitization.
- Use a content security policy to constrain where data URIs are permitted, since a policy can restrict or forbid them for scripts and other sensitive contexts.
- Be cautious about treating a data URI as a same-origin resource; its behavior differs from a normal fetched file.
Treat data URIs from external or user-supplied sources with the same suspicion you would apply to any untrusted input.
How do data URIs compare to linking a file?
| Aspect | Data URI | Linked file |
|---|---|---|
| Network requests | None for the asset | One request per asset |
| Independent caching | No | Yes |
| Size overhead | Base64 adds about one third | None beyond the file |
| Best for | Tiny, page-specific assets | Shared or larger assets |
| Reuse across pages | Re-downloaded each time | Cached and reused |
Choose data URIs deliberately for the small-asset, latency-sensitive case, and fall back to conventional linked, cacheable resources for everything else.
Frequently asked questions
What is the syntax of a data URI?
It is data: followed by an optional media type, an optional ;base64 flag, a comma, and then the data. For example data:text/plain;base64,SGk= encodes the text Hi.
When should data be base64 encoded?
Use base64 for binary data such as images and fonts. Text-based data can be included directly, often percent-encoded, which is more compact than base64 for small text.
Do data URIs get cached by the browser?
Not independently. Because the data is embedded in the referencing document or stylesheet, it is cached only as part of that resource and cannot be cached or reused on its own.
What is the default media type for a data URI?
If you omit the media type, the default is text/plain with a US-ASCII character set, per the data URL specification.
Are data URIs good for large files?
No. Base64 inflates size by roughly a third, the encoded data cannot be cached separately, and very long URIs strain parsers, so data URIs suit small assets only.
Can data URIs pose security risks?
Yes. A data URI can carry executable content such as HTML or scripts, so treat untrusted data URIs carefully and constrain them with a content security policy.
Does a data URI reduce HTTP requests?
Yes, because the resource is embedded rather than fetched separately, which can help for a few tiny assets, though it trades away separate caching.