ScreenshotNeo

BlogHow-to

How to Use HTML Image Data URLs

Learn the correct HTML data URL syntax, base64 and percent encoding, accessibility, CSP fixes, size limits, and when to use normal image files.

By the ScreenshotNeo team1 October 20267 min read

To embed an image data URL in HTML, put the complete data: URL in an <img> element’s src attribute:

<img
  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='red'/%3E%3C/svg%3E"
  alt="Red square"
  width="32"
  height="32"
>

This example uses a percent-encoded SVG. For binary formats such as PNG or JPEG, use the form data:image/png;base64,<base64-data>. Data URLs are best for small, self-contained images. Larger or reused images are usually better as normal files because data URLs increase HTML size and do not provide ordinary URL caching.

1. Understand the data URL format

RFC 2397 defines the general syntax as:

data:[<mediatype>][;base64],<data>

The comma separates the metadata from the payload. The media type should describe the actual image bytes, such as image/png, image/jpeg, image/gif, image/webp, or image/svg+xml. If you omit the media type, the historical default is text/plain;charset=US-ASCII, which is not an appropriate default for an image. See RFC 2397 and the HTML Standard’s img element.

Base64 example

<img
  src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB..."
  alt="A one-pixel transparent image"
  width="1"
  height="1"
>

The shortened payload above is illustrative. A browser needs the complete Base64 representation of the PNG bytes. Do not include spaces, line breaks, Markdown backticks, or a second comma inside the payload.

Percent-encoded SVG example

<img
  src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ccircle cx='50' cy='50' r='40' fill='%230078d4'/%3E%3C/svg%3E"
  alt="Blue circle"
  width="100"
  height="100"
>

Without ;base64, characters that are not safe in a URL must be percent-encoded. In the example, < becomes %3C, > becomes %3E, and the color character # becomes %23.

2. Choose Base64 or percent encoding

Encoding Use it for Important details
Base64 Binary bytes from PNG, JPEG, GIF, WebP, or any other binary image Prefix with the exact media type and ;base64,. Standard Base64 uses +, /, and optional = padding.
Percent encoding Textual formats such as SVG Escape reserved characters, spaces, newlines, and control characters. The comma after the metadata remains the delimiter.

Base64 is text, but it is not a compression format. Its representation is commonly larger than the original binary bytes, and the encoded content becomes part of every HTML response that contains it. RFC 2397 describes the scheme as useful for short values; it is not a general replacement for image files.

Generate a Base64 data URL with command-line tools

# Linux
printf '...binary image bytes...' | base64 -w 0

# macOS
base64 < image.png | tr -d '\n'

Prepend the result with data:image/png;base64,. Confirm that the file really is a PNG before choosing that media type.

Generate one with Python

from base64 import b64encode
from pathlib import Path

raw = Path("image.png").read_bytes()
data_url = "data:image/png;base64," + b64encode(raw).decode("ascii")
print(data_url)

Generate one with Node.js

import { readFileSync } from "node:fs";

const bytes = readFileSync("image.png");
const dataUrl = `data:image/png;base64,${bytes.toString("base64")}`;
console.log(dataUrl);

3. Write accessible HTML

The data URL does not change normal image accessibility rules. Provide alt text that communicates the image’s purpose:

<img src="data:image/webp;base64,..." alt="Revenue trend for the last quarter">

If the image is purely decorative or its meaning is already supplied by nearby text, use an empty value:

<img src="data:image/svg+xml,%3Csvg ...%3E...%3C/svg%3E" alt="" aria-hidden="true">

Do not omit alt. Set width and height when you know the dimensions so the browser can reserve layout space before decoding the image.

4. Check Content Security Policy when the image is blocked

A page’s Content Security Policy (CSP) can reject a valid data URL. The img-src directive controls image and favicon sources. If img-src is absent, the browser applies default-src as the fallback. Read the policy from the response headers or a <meta http-equiv="Content-Security-Policy"> element.

Content-Security-Policy: default-src 'self'; img-src 'self' data:

That policy permits images from the site’s own origin and from the data: scheme. Add only the source your application needs and keep the rest of the policy unchanged. The MDN img-src reference documents the directive and its fallback behavior.

Typical console messages include “Refused to load the image” or a report that the data scheme is not allowed. If you cannot change the policy, store the image at an allowed HTTPS URL instead.

5. Know the practical limits

  • Keep payloads small. Large data URLs make HTML downloads, parsing, memory use, and DOM inspection more expensive.
  • Do not rely on a universal maximum. Browser and intermediary limits vary, so historic HTML attribute limits are not a portable current limit.
  • Reuse changes the trade-off. A separate image can be cached and reused across pages; an inline value is duplicated in each document.
  • Updates require HTML changes. Replacing an external file can preserve the document; replacing a data URL changes the document bytes.
  • There is no relative URL. The payload is opaque. Appending ?size=small does not create a normal query string.

Use a data URL for tiny icons, generated placeholders, single-file demos, email templates with known client constraints, or a self-contained artifact. Prefer a normal image URL, responsive images, or an image pipeline for photographs, large illustrations, and assets used on multiple pages.

6. Security and browser behavior

An img element must load an image resource; it must not treat arbitrary non-image data as an image. Executable code embedded in an image resource is not run merely because the resource is in a data URL. That does not make untrusted input safe: validate generated SVG, escape text inserted into SVG, and do not assume a data URL bypasses CSP.

Modern browsers give navigated data URLs opaque origins and restrict top-level navigation to data URLs as a security measure. These navigation rules are separate from embedding an image in img. See the WHATWG URL Standard and Fetch Standard for current URL processing details.

7. Troubleshooting checklist

Symptom Likely cause Fix
Broken-image icon Missing comma, truncated payload, or invalid encoding Check the exact data:[type][;base64],payload structure and regenerate the complete value.
Image displays as text Media type omitted or incorrect Use the real type, such as image/png or image/svg+xml.
Works locally but not in production CSP disallows data: Permit data: under img-src if policy allows, or use an approved HTTPS image URL.
SVG fails to render Unescaped <, #, quotes, whitespace, or newlines Percent-encode the SVG, or generate a Base64 SVG data URL.
PNG or JPEG fails after conversion URL-safe Base64 or inserted line breaks Use standard Base64 and remove whitespace; keep the correct padding.
Page becomes slow Large inline payloads increase HTML and decoding work Move the asset to a separate file and use normal caching or responsive image delivery.
Image has the wrong colors or format Declared media type does not match the bytes Inspect the file signature and regenerate with the matching MIME type.

8. Decide between a data URL and a separate image

Question Data URL Separate image URL
Is the asset tiny and used once? Often convenient Also works
Will many pages reuse it? Duplicates bytes in each HTML document Browser and CDN caching can reuse it
Does the site have a strict CSP? Requires an allowed data: source Can use the site’s approved origin
Will the image change independently? Requires changing HTML Replace the file independently
Is it a large photo or screenshot? Usually a poor fit Use a normal URL or image service

9. Or skip the browser setup

If your goal is to obtain an image for HTML rather than manually build a data URL, ScreenshotNeo returns a PNG, JPEG, WebP, or PDF from one GET request. Its API can capture the page you need without maintaining browser automation.

See the ScreenshotNeo API documentation for all options. This basic request captures a page as WebP:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Before capture, cookie and consent banners, newsletter popups, and chat widgets are removed. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. ScreenshotNeo also provides an MCP server for AI agents, including Claude and Cursor, with take_screenshot, get_page_info, and capture_pdf tools. The Free plan includes 1,000 screenshots each month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

10. FAQ

Can I use a data URL in CSS instead of HTML?

Yes. CSS properties such as background-image accept URL values, including data URLs, subject to the page’s CSP and the same encoding rules.

Should I use Base64 for every image?

No. Base64 is useful for binary bytes that must be inline, but it increases the representation size. Use a normal image URL for assets that are large or reused.

Does a data URL need quotes in src?

Quote the attribute. Quotes make the full value unambiguous, especially when the payload contains punctuation or encoded whitespace.

Can I append a cache-busting query to a data URL?

No. A data URL’s payload is opaque; query-string behavior for ordinary HTTP URLs does not apply.