Fixing the globe cursor in HTML5 Drag and Drop

07 Aug 2023

While building Relume's new Sitemap tool we ran into an issue when dragging things; you'd see a weird globe icon near your cursor:

Globe icon drag cursor

This was a gnarly issue to debug because it occurred inside Chrome on Mac; on other browsers & platforms there was no globe or weird cursor at all. I don't use a Mac, so thanks to my teammates for spotting the issue.

There didn't seem to be good advice on the internet for our use case. One report related to dragging <a> elements; this didn't fix it for us, and we didn't have any <a> elements. Another lead was setting -webkit-drag-image but that didn't fix the issue either.

As it turns out, the issue was caused by our drag image. In retrospect is sounds so obvious; the "globe" icon is the drag image used on MacOS when the real image hasn't finished loading.

The offending code was:

function onDragStart(event: DragEvent) {
  // ...
  // This code causes the issue:
  event.dataTransfer.setDragImage(new Image(), 0, 0);

This code should have replaced the OS's drag preview image with an empty image. We do that so we can render the drag preview using DOM elements ourselves; with the image the browser renders a cut-off ghost of the element. Since the Image element is constructed at the same time as the drag start, it doesn't finish loading before the browser tries to use it. On MacOS Chrome, this results in the dreaded globe icon.

The solution is simple. We create the image on page load, so it'll be loaded when the user starts dragging:

// 1x1 transparent pixel.  If we use a 0x0 image, Firefox
// would ingore it and fallback to the default.
export const EMPTY_IMAGE = new Image(1, 1);
EMPTY_IMAGE.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==';


function onDragStart(event: DragEvent) {
  // ...
  // If the image isn't complete, Safari will abort the drag.
  // Double check to be safe:
  if (emptyImage.complete) {
    event.dataTransfer.setDragImage(emptyImage, 0, 0);

Hope that helps if you're building with the HTML5 DnD api.

This post is about work I've been doing at Relume.
Relume helps agencies and freelancers design websites faster.
Learn more at relume.io.