Skip to main content

External Link Warning

Put this in the advanced body section. Note the issue at the top of the script where you can adjust if external links open in the same tab or a new one

Advanced Body Script 

<script>
document.addEventListener("DOMContentLoaded", function () {

    // USE THIS TO CONFIGURE LINK OPENING BEHAVIOR.
    // true = load in new tab
    // false = load in same tab
    // There is an issue where when set to true, browsers will consider it a pop-up if you let it count down
    const OPEN_IN_NEW_TAB = false;

    function handleExternalLink(event) {
        event.preventDefault(); // Prevent default link behavior

        let externalUrl = this.dataset.externalHref; // Get the stored URL

        let existingModal = document.getElementById("exit-warning-modal");
        if (existingModal) existingModal.remove();

        let truncatedUrl = externalUrl.length > 30 ? externalUrl.substring(0, 30) + "..." : externalUrl;

        let modal = document.createElement("div");
        modal.id = "exit-warning-modal";
        modal.setAttribute("role", "dialog");
        modal.setAttribute("aria-labelledby", "modal-heading");
        modal.setAttribute("aria-describedby", "modal-message");
        modal.setAttribute("aria-modal", "true");
        modal.style = `
            position: fixed; top: 0; left: 0; width: 100%; height: 100%;
            background: rgba(0, 0, 0, 0.5); display: flex; align-items: center;
            justify-content: center; z-index: 9999;
        `;

        modal.innerHTML = `
            <div style="background: white; max-width: 500px; padding: 20px;
                border-radius: 5px; text-align: center; box-shadow: 0 4px 10px rgba(0,0,0,0.2);
                position: relative;">
                <h2 id="modal-heading" style="margin-bottom: 10px;">You Are Leaving This Website</h2>
                <p id="modal-message" style="font-size: 16px;">
                    You are about to leave our website and visit an external site. We do not endorse or take responsibility for the content on external sites. 
                    Please ensure that the site you are visiting is secure.
                </p>
                <p id="url-preview" style="font-size: 16px; font-style: italic; color: #595959;"
                    title="${externalUrl}" aria-label="External URL preview: ${externalUrl}">
                    (${truncatedUrl})
                </p>
                <p style="font-size: 16px; font-weight: bold;">You will be redirected in <span id="countdown">10</span> seconds...</p>
                <button id="cancel-exit" style="margin-right: 10px; padding: 8px 12px; background: #ccc; color: black; border: none; cursor: pointer; border-radius: 3px;">Cancel</button>
                <button id="proceed-exit" style="padding: 8px 12px; background: #0056B3; color: white; font-weight: bold; border: none; cursor: pointer; border-radius: 3px;">Proceed</button>
            </div>
        `;

        document.body.appendChild(modal);

        modal.querySelector("#proceed-exit").focus();

        let countdown = 10;
        let countdownInterval = setInterval(function () {
            countdown--;
            document.getElementById("countdown").textContent = countdown;
            if (countdown <= 0) {
                clearInterval(countdownInterval);
                if (OPEN_IN_NEW_TAB) {
                    window.open(externalUrl, "_blank");
                } else {
                    window.location.href = externalUrl;
                }
            }
        }, 1000);

        document.getElementById("cancel-exit").addEventListener("click", function () {
            clearInterval(countdownInterval);
            modal.remove();
        });

        document.getElementById("proceed-exit").addEventListener("click", function () {
            clearInterval(countdownInterval);
            if (OPEN_IN_NEW_TAB) {
                window.open(externalUrl, "_blank");
            } else {
                window.location.href = externalUrl;
            }
        });

        window.addEventListener("focus", function () {
            if (document.visibilityState === "hidden") {
                modal.remove();
                clearInterval(countdownInterval);
            }
        });

        document.addEventListener("keydown", function (e) {
            if (e.key === "Escape") {
                modal.remove();
                clearInterval(countdownInterval);
            }
        }, { once: true });
    }

    function modifyExternalLinks() {
        let links = document.querySelectorAll("a[href]");

        links.forEach(link => {
            let href = link.getAttribute("href");

            if (
                /^https?:\/\//.test(href) &&
                !href.startsWith(window.location.origin) &&
                !link.closest(".cke_dialog") &&
                !/^javascript:/i.test(href)
            ) {
                link.dataset.externalHref = href;
                link.removeAttribute("href"); 
                link.style.cursor = "pointer"; 
                link.addEventListener("click", handleExternalLink);
            }
        });
    }
    modifyExternalLinks();
    const observer = new MutationObserver(modifyExternalLinks);
    observer.observe(document.body, { childList: true, subtree: true });
});
</script>