Inline SVG <img> using ServiceWorker

This is more of an experiment, I have no idea why one might want to use this in production.

So, the idea is to replace img tag with contents of SVG file it references to. In other words: inline the image into HTML.

We want to write HTML like this:

<img src="image.svg">

But give to the browser something like this:

<svg width="35" height="35" viewBox="0 0 35 35" xmlns=""><title>×</title><path d="M.608 29.304l5.472 5.472 11.592-11.592 11.52 11.592 5.472-5.472-11.592-11.52 11.592-11.52L29.192.792l-11.52 11.52L6.224.792.752 6.264 12.2 17.784.608 29.304z" fill="#000" fill-rule="evenodd"/></svg>

This can be done easily from within ServiceWorker. Whenever the browser is requesting an HTML, we want to fetch that HTML behind the scenes, as well as the image and then just replace img tag with the contents of that SVG file. Finally construct a response object with transformed HTML and send it back to the browser.

self.addEventListener('fetch', (event) => {

if (event.request.url.includes('index.html')) {

// fetch HTML
.then((res) => res.text())
.then((html) => {

// fetch SVG
return fetch('image.svg')
.then((res) => res.text())
// replace <img> with SVG contents
.then((svg) =>
html.replace('<img src="image.svg">', svg))
// respond with a new HTML
.then((html) => new Response(html, {
headers: new Headers({
'Content-Type': 'text/html'

The code above is extremely simple. Of course you might want to parse HTML first, find all img tags with SVGs, do transformation and cache transformed HTML. But, why on earth you might want to do it?

A gist with code.