JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/FileSaver.min.js"></script>
<form>
    <textarea style="width:400px;height:100px;" id="json" placeholder="Paste your GIF backup here"></textarea>
    <br />
    <input id="submit" type="button" value="Parse" />
</form>

<span id="message1"></span>

JavaScript

const form1 = document.getElementsByTagName("form")[0];
const json1 = form1.querySelector('#json');
const button1 = form1.querySelector('#submit');
const message1 = document.querySelector('#message1'); // or just message1 since global

function isValidUrlStart(urlString) {
  let regEx = /^https?:.*$/;

  return regEx.test(urlString);
}

button1.addEventListener("click", function (evt) {
    evt.preventDefault();
    
    if (json1.value.length == 0)
    {
    		return false;
    }

    try {
        const backup = JSON.parse(json1.value);

        let outbuf = `<!doctype html>
<titl>Gif export</titl e>
<body>
<h4>Please be sure to save this page, as it is temporary. Use CTRL+S and save it as "HTML Only".</h4>
<h3>Your gifs: </h3>
<ul>
`;
        let data = backup?._state?.favorites;

        if (data === undefined) {
            data = backup.default;
        }

        for (const y of data) {
            let urlSrc = !isValidUrlStart(y.src) ? `https:${y.src}` : y.src;

            outbuf += `<li><a href="${y.url}">${y.url} (${urlSrc})</a>\n<br/>`;

            if (y.format === "VIDEO") {
                outbuf += `<video controls loop autoplay muted src="${urlSrc}"></video>`;
            } else {
                outbuf += `<img src="${urlSrc}"/>`;
            }

            outbuf += `</li>`;
        }

         outbuf += "</ul>\n</body>";

        saveAs(new Blob([outbuf], { type: "text/html" }), "gif-export.html");
      
        message1.innerHTML = "Open downloaded file in a browser to see GIF export";
    } catch(exc) {
        alert(`Failed to parse the gif backup: "${exc}"`);

        return false;
    }
});