fast js to augment specific urls
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

we are going to proxy our images through cloudinary at run time. the way this works is something like {cloudinaryurl.com/bunch of transform params/}+{https://original url to image} the issue for us is that our backend only serves relative urls to the front so we are ending up with something like {cloudinaryurl.com/bunch of transform params/}+{/localpath to image} which wont work. So to avoid refactoring a ton of things we thought about getting some js to execute on the page as quickly as possible to add in the domain that the page is loaded on and inject it to the url path of the image. so it would be something like

{cloudinaryurl.com/bunch of transform params/}+{injectdomain}{/localpath to image}

then we end up with the real url we needed and it will resolve nicely. so here is what we need from you. vanila js, no jquery code to quickly scan the html looking for some identifier and replace it with the domain that is in the url bar. if you need us to add any sort of attributes to the <img element we certain can without any issues. for example if we need to do something like <image scr="" domain-inject"true" to make it faster for you to scan then we can. so imagine something like this

<img src="`https://res.cloudinary.com/apikey/image/fetch/c_fill,g_auto,h_640,w_640/q_auto/@/content/dam/creative-assets/weleven/landing-page/Orange%20couch.png" domain-inject=true">`  

then you find the data element and replace the @ symbol with the domain.

the code should work on all major browsers including mobile, it should rely on ny external dependencies so its fast and lightweight

awarded to Wuddrum

Crowdsource coding tasks.

1 Solution

Winning solution

Here's what I came up with:

var injectionAttribute = "data-inject-domain";

function processImageElement(imgEl) {
    if (!imgEl.hasAttribute(injectionAttribute)) {
        return;
    }

    var src = imgEl.getAttribute(injectionAttribute);
    src = src.replace("@", window.location.origin);

    imgEl.removeAttribute(injectionAttribute);
    imgEl.setAttribute("src", src);
}

function onMutations(mutationList) {
    for (var i = 0; i < mutationList.length; i++) {
        var mutation = mutationList[i];
        mutation.addedNodes.forEach((node) => {
            if (
                node.tagName === "IMG" &&
                node.hasAttribute(injectionAttribute)
            ) {
                processImageElement(node);
                return;
            }

            if (!node.querySelectorAll) {
                return;
            }

            var imgEls = node.querySelectorAll("img[data-inject-domain]");
            imgEls.forEach(processImageElement);
        });
    }
}

var mutationObserver = new MutationObserver(onMutations);
mutationObserver.observe(document.documentElement, {
    childList: true,
    subtree: true,
});

This will also work on dynamically inserted images, so there's no need to re-run the code

Usage:

1. Put the code in script tags inside the document header

2. Change existing img tags to contain a data-inject-domain attribute with the desired URL, where the symbol @ will get replaced with current protocol and domain name

Example: <img src="data:," alt="Example" data-inject-domain="@/content/image.jpg" /> would become <img src="https://example.com/content/image.jpg" alt="Example" /> after the script has processed the img tag