How to turn an image into a data URI string
By Flavio Copes
Learn how to turn an image file into a data URI string in Node.js by reading it and base64-encoding it with Buffer, then embed it directly inside an img tag.
To turn an image into a data URI string in Node.js, read the file, base64-encode it with Buffer, and prepend the data:<content type>;base64, prefix. The result is a string you can put straight into an img tag.
A data URI is a URL that contains the file’s data instead of pointing to it. It looks like this:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUg...
The browser decodes it on the spot, so the image needs no extra HTTP request and no separate file. That’s handy for single-file HTML pages, emails, and generated documents.
The code
I had an image file on my filesystem and I wanted to put it inside an HTML page using the data-uri format so I could embed it into the page itself.
Here’s how I did it:
const imageData = fs.readFileSync(fileLocation, 'binary')
const src = `data:${contentType};base64,${Buffer.from(
imageData,
'binary'
).toString('base64')}`
We read the raw bytes, wrap them in a Buffer, and toString('base64') gives us the encoded payload. Remember to require('fs') at the top.
contentType is the image’s MIME type. For a local file you know it from the extension: image/png, image/jpeg, image/webp, and so on.
In my case I just download that image from the Internet, so I retrieved contentType from the response headers:
const contentType = response.headers['content-type']
In the end I was able to use src inside an img tag like this: <img src={src} />
When the image doesn’t show up
If the browser renders a broken image icon, check the prefix first. The two mistakes I’ve made: a wrong MIME type (declaring image/png for a JPEG file), and forgetting the ;base64 part. Without that marker the browser tries to read the payload as plain text and gives up.
Log the first 50 characters of src and compare them with the example at the top of this post. The bug is almost always there, not in the encoded data.
One thing to keep in mind
Base64 encoding makes the data about 33% bigger than the original file. For an icon or a small logo that’s irrelevant. For a large photo it bloats your HTML, and unlike a normal image URL, the browser can’t cache it separately from the page. I use data URIs for small images only.
If you just want to drop an image file and copy the data URI without writing that script, I built a free Base64 image encoder that runs in your browser.
Related posts about node: