Skip to content

Instantly share code, notes, and snippets.

@axoplasm
Created March 5, 2026 23:29
Show Gist options
  • Select an option

  • Save axoplasm/0f219e5c26eadedc3cd9f807dc83c826 to your computer and use it in GitHub Desktop.

Select an option

Save axoplasm/0f219e5c26eadedc3cd9f807dc83c826 to your computer and use it in GitHub Desktop.
Wagtail shim to fix HEIC crashes in Safari/Mac

Enabling support for HEIC images in Wagtail 7.3 can cause unwanted behaviors in Safari. See:

Luckily we can patch this in the admin. First, add a Wagtail hook in your app’s wagtail_hooks.py file:

# project_root/your_wagtail_app/wagtail_hooks.py

import wagtail.hooks as hooks
from django.utils.html import format_html

@hooks.register('insert_global_admin_js')
def global_admin_js():
    return format_html('<script src="{}"></script>', static('wagtail/admin.js'))

Which loads this shim:

/* project_root/your_wagtail_app/static/wagtail/admin.js */

(function () {
    // Safari on macOS crashes when a file input's accept attribute includes image/heic.
    // Detect Safari (excluding Chrome/Edge/Opera which include "Safari" in their UA strings).
    var isSafari =
        /Safari/i.test(navigator.userAgent) 
        && /Macintosh/.test(navigator.userAgent)
        && !/Chrome|CriOS|EdgA|OPR/i.test(navigator.userAgent);

    if (!isSafari) return;

    function stripHeic(input) {
        var accept = input.getAttribute("accept");
        if (!accept || !accept.includes("image/heic")) return;
        var fixed = accept
            .split(",")
            .map(function (s) { return s.trim(); })
            .filter(function (s) { return s !== "image/heic"; })
            .join(", ");
        input.setAttribute("accept", fixed);
    }

    function fixAll() {
        document
            .querySelectorAll('input[type="file"][accept*="image/heic"]')
            .forEach(stripHeic);
    }

    // Fix inputs already in the DOM at load time
    document.addEventListener("DOMContentLoaded", fixAll);

    // Watch for inputs added dynamically by the Wagtail admin UI
    function startObserving() {
        new MutationObserver(function (mutations) {
            mutations.forEach(function (mutation) {
                mutation.addedNodes.forEach(function (node) {
                    if (node.nodeType !== 1) return;
                    if (node.matches('input[type="file"][accept*="image/heic"]')) {
                        stripHeic(node);
                    }
                    node
                        .querySelectorAll('input[type="file"][accept*="image/heic"]')
                        .forEach(stripHeic);
                });
            });
        }).observe(document.body, { childList: true, subtree: true });
    }

    if (document.body) {
        startObserving();
    } else {
        document.addEventListener("DOMContentLoaded", startObserving);
    }
})();

This is a static JS file with no dependencies. It doesn’t need to be included in the Wagtail admin build.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment