Use Case
As a person wanting to annotate a IIIF resource, you would like to open a Manifest in a viewer not available in the web interface where you first find the resource.
Alternately, as a viewer developer, you would like to allow your viewer to receive dragged-over items.
Implementation Notes
Implementing this recipe requires a resource provider and a viewer each to implement their part.
For Resource Providers
The resource provider must have a draggable item — customarily the IIIF logo image — that makes use of the DataTransfer object. It will have a dataTransfer.setData method attached to the item’s dragstart event. It can be helpful to turn the cursor into a pointer when it hovers over the draggable IIIF logo image, to indicate that it is draggable.
A script implementing such a method for a Manifest could look like the below.
<script>
function drag(ev) {
ev.dataTransfer.setData("text/plain", JSON.stringify({
"@context": "http://iiif.io/api/presentation/3/context.json",
"id": "https://iiif.io/api/cookbook/recipe/0599-drag-and-drop/dnd-manifest",
"type": "Annotation",
"motivation": ["contentState"],
"target": {
"id": "https://iiif.io/api/cookbook/recipe/0006-text-language/manifest.json",
"type": "Manifest"
}
}));
}
</script>
Note that the script represents the manifest content as JSON to parallel other cookbook resource content, but converts it to a string to match the content type parameter. While the setData method of Web Assembly can use other content types, the spec for IIIF Content State requires a content type of text/plain for maximum compatibility.
The content does not have to be a full Manifest. A script implementing this same method for a single Canvas of a Manifest could look like the below. (Noting that there would be no likely practical difference from the above since this manifest contains but one Canvas.)
<script>
function drag(ev) {
ev.dataTransfer.setData("text/plain", JSON.stringify({
"@context": "http://iiif.io/api/presentation/3/context.json",
"id": "https://iiif.io/api/cookbook/recipe/0599-drag-and-drop/dnd-manifest",
"type": "Annotation",
"motivation": ["contentState"],
"target": {
"id": "https://iiif.io/api/cookbook/recipe/0006-text-language/canvas/p1",
"type": "Canvas",
"partOf": [{
"id": "https://iiif.io/api/cookbook/recipe/0006-text-language/manifest.json",
"type": "Manifest"
}]
}
}));
}
</script>
For Viewer Developers
A supporting viewer must have an interface capable of handling the DataTransfer object’s data carried by the draggable item in its drop event. Somewhat as for resource providers, the getData method of Web Assembly can specify other content types but the spec for IIIF Content State requires a content type of text/plain for maximum compatibility. See the immediately following section for cautions about receiving content.
Restrictions
Because implementation is two-part, you may only have control over one half of the ability to drag and drop. Consequently, and since this action is only in a GUI environment, you will need to consider whether visitors to your IIIF interface would benefit from some kind of support text.
Viewer developers will have a special need to consider security when implementing a droppable interface. This recipe cannot cover all of data transfer security, but will note that all content provided to a site should be sanitized.
Example
Below is an image of the IIIF logo, decorated with the appropriate JavaScript event handler attributes, and a visible version of the markup for that image, showing the connection to the page script for the drag event. For a supporting viewer, the IIIF logo image below could be dragged onto its viewing area and dropped, which would result in the viewer retrieving the manifest for the IIIF Cookbook recipe titled “Internationalization and Multi-language Values”.
No viewers currently support this approach to dragging and dropping a manifest.

<img src="logo-sm.png" draggable="true" ondragstart="drag(event)" alt="IIIF logo; drag and drop onto a supporting viewer to see this resource in that viewer" style="cursor:grab;">
Though no viewer supports it, IIIF-C Technical Director Glen Robson has a working version of a non-canonical viewer implementation publicly available. This brief screencast demonstrates what it could look like to use that viewer:
Related Recipes
- Sharing a link for opening two or more Canvases for another use of IIIF Content State