@mango-iiif/iiif-viewer
v0.5.2
Published
A Svelte-based viewer and story toolkit for IIIF resources.
Maintainers
Readme
Mango IIIF Viewer
Mango is a flexible IIIF viewer and storytelling toolkit for museums, libraries,
archives, galleries, and digital scholarship projects. It can be added directly
to an existing website as <mango-viewer> or installed as an npm dependency in
a JavaScript, React, Vue, or Svelte application.
Mango brings images, audio, video, PDFs, 3D models, annotations, metadata, and search into one responsive interface.
Why Mango?
- One viewer for varied collections — deep-zoom images, audio/video, PDF, and GLB/GLTF models use a shared navigation and metadata experience.
- IIIF-aware — reads common Presentation 2 and 3 resources, Image API services, external annotations, language maps, and Content Search services.
- Easy to embed — use a standalone module on a normal HTML page or install the framework-neutral custom element from npm.
- Built for interpretation — publish guided stories or use the story builder to capture canvases, viewports, media segments, narration, text, model poses, and layer settings.
- Annotation workflows — display W3C/IIIF annotations, draw local shapes, and connect export events to an institution's storage service.
- Institution-ready presentation — configure panels, layouts, themes, languages, OpenSeadragon, A/V behaviour, and responsive sizing.
- Extensible — plugins receive a DOM mount point, typed viewer API, event bus, and configuration without requiring a Mango fork.
Fastest start: standalone website
No application framework or build step is required:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Collection item</title>
<style>
.viewer-shell {
width: 100%;
}
mango-viewer {
display: block;
width: 100%;
/* Optional: Mango defaults to 720px, capped by the small viewport. */
height: min(75vh, 800px);
}
</style>
</head>
<body>
<div class="viewer-shell">
<mango-viewer
mode="viewer"
manifest-id="https://example.org/iiif/manifest.json"
config='{"theme":"light","language":"en"}'
></mango-viewer>
</div>
<script
type="module"
src="https://cdn.jsdelivr.net/npm/@mango-iiif/iiif-viewer@latest"
></script>
</body>
</html>The viewer has a default height of 720px, capped by the small viewport so it
fits on phones. Override it with ordinary site CSS as above, or set
--mango-viewer-height; its parent does not need an explicit height. Replace
the example Manifest URL with a resource that permits cross-origin browser
requests. Pin an exact package version before deploying to production.
See the standalone and npm getting-started guide for troubleshooting and production guidance.
Install from npm
npm install @mango-iiif/iiif-viewer svelteRegister the custom element once in the application entry point:
import "@mango-iiif/iiif-viewer/element";Then use it in HTML or a framework template:
<mango-viewer
mode="viewer"
manifest-id="https://example.org/iiif/manifest.json"
></mango-viewer>Complex configuration is best assigned as a JavaScript property:
await customElements.whenDefined("mango-viewer");
const viewer = document.querySelector("mango-viewer");
viewer.config = {
theme: "light",
language: "en",
showMetadata: true,
showSearch: true,
sidebar: {
enabled: true,
open: true,
activePanel: "metadata",
},
};theme and language belong inside config; they are not separate custom
element attributes.
JavaScript class API
Applications that want an explicitly mounted class can use Mango:
import { Mango } from "@mango-iiif/iiif-viewer";
import "@mango-iiif/iiif-viewer/style.css";
const target = document.querySelector("#viewer-host");
if (!target) throw new Error("Missing #viewer-host");
const viewer = new Mango({
target,
manifestId: "https://example.org/iiif/manifest.json",
config: { theme: "light", language: "en" },
});
const unsubscribe = viewer.on("pageChange", ({ index, canvasId }) => {
console.log(`Canvas ${index + 1}: ${canvasId}`);
});
viewer.setCanvasByIndex(2);
// When the host permanently removes the viewer:
unsubscribe();
viewer.destroy();The package also exports a native Svelte 5 component. See application integrations for React 18/19, Vue 3, Svelte, custom-element properties, and package entry points.
Viewer modes
The same custom element supports several collection and authoring experiences:
| Mode | Purpose | Primary input |
| ------------------- | ------------------------------- | ------------------------------- |
| viewer | Browse a single IIIF Manifest | manifest-id |
| workspace | Arrange multiple viewer windows | viewer UI |
| annotation-editor | Draw and export annotations | manifest-id |
| story-viewer | Play a guided narrative | story-url or story |
| story-builder | Author and export a narrative | optional story-url or story |
<mango-viewer
mode="annotation-editor"
manifest-id="https://example.org/iiif/manifest.json"
></mango-viewer><mango-viewer
mode="story-viewer"
story-url="/stories/exhibition-tour.json"
></mango-viewer>Host-managed story storage
Story Builder can save to browser-owned storage such as IndexedDB by assigning an asynchronous handler in JavaScript. The handler receives the portable IIIF AnnotationPage produced by the builder:
const builder = document.querySelector("mango-viewer");
builder.config = {
story: {
save: {
handler: async (story) => {
await storiesDatabase.put(story);
return { ok: true, message: "Saved locally" };
},
},
},
};The current editable state and IIIF export can also be read on demand with
builder.getStory() and builder.exportStory(). Both return null outside
Story Builder mode or before the builder is ready. The storySaveRequest and
storyExport events expose the same portable document when the corresponding
toolbar actions are selected.
Documentation
The Mango GitHub Wiki contains the complete user and contributor documentation:
| Guide | What it covers | | ----------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | | Getting started | Standalone websites, npm installation, modes, and blank-viewer troubleshooting | | Configuration | Panels, layouts, OSD, PDF, 3D, A/V, stories, and all first-party options | | Application integrations | JavaScript, React, Vue, Svelte, and package entry points | | JavaScript API | Navigation, viewports, media, models, layers, annotations, and state | | Events | DOM and class events, payloads, persistence, and analytics examples | | Theming and languages | Built-in themes, CSS variables, language selection, and translation contributions | | Plugins | Plugin contract, slots, lifecycle, registration, and a complete example | | Story viewer and builder | IIIF AnnotationPage stories, model/layer state, authoring, and saving | | IIIF and W3C support | Supported standards, evidence boundaries, and current limitations | | Deployment and accessibility | CORS, CSP, accessibility, privacy, authentication, and production checks | | Developer guide | Architecture, local development, testing, builds, and contribution workflow |
IIIF support
Mango provides broad but intentionally documented partial support for IIIF Presentation 2 and 3, Image API services, W3C Web Annotation, and Content Search 1 and 2. Important current limitations include:
- no general Collection hierarchy browser;
- incomplete
viewingDirection, Range, Choice, and multi-body workflows; - incomplete IIIF Content State handling; and
- no built-in IIIF Authentication interaction/token flow.
Mango's audio/video request hooks can participate in an access strategy owned by the host application, but they do not make the viewer a complete Authentication API client. Read the support matrix before adopting Mango for restricted or unusually complex resources.
Supporting packages
Mango delegates focused responsibilities to other @mango-iiif packages:
@mango-iiif/w3c-parserparses W3C annotations and spatial/temporal selectors.@mango-iiif/annotationprovides OpenSeadragon annotation interaction and drawing.@mango-iiif/iiif-search-clientdiscovers and queries IIIF Content Search services.@mango-iiif/avprovides audio/video playback, chapters, captions, transcripts, and related UI.
Development
npm ci
npm run devUseful verification commands:
npm test
npm run test:e2e
npm run build:types
npm run lint
npm run build:demo
npm pack --dry-runBrowser-facing changes should be verified against the real built demo entry point. Public API changes should update exported types, tests, examples, and the wiki together.
Read the developer and architecture guide before contributing.
Project status and feedback
Mango is actively developed. Please review the known limitations and test representative institutional resources before production adoption.
Report bugs and request features through GitHub Issues. A useful report includes the Mango version, browser, viewer mode/configuration, a reduced public IIIF fixture, and relevant console or network errors.
License
Mango is available under the MIT License.
