This article explains how to use the Mirador viewer to display IIIF images.

Reference Implementation

The embedding approach is based on the Stanford Digital Repository by Stanford University Libraries. The viewer is embedded above bibliographic information, allowing metadata and images to be viewed on the same page.

File Structure

apps/web/
├── public/mirador/
│   └── index.html          # Mirador viewer
├── src/components/item/
│   └── MiradorViewer.tsx   # Embedding component
└── .env.local              # Environment variable settings

URL Parameters

/mirador/index.html accepts the following URL parameters:

ParameterDescriptionExample
manifestIIIF manifest URL (required). Multiple values can be specified separated by semicolonshttps://example.com/iiif/manifest.json
embedEmbed mode (true hides the close button and left menu)true
themeTheme (dark or light)dark
langLanguage code (default: ja)ja, en
canvasCanvas ID for initial display-
annotationStateAnnotation display mode (true opens the sidebar)true

Usage Example

/mirador/index.html?manifest=https://example.com/iiif/manifest.json&embed=true&theme=dark&lang=ja

Mirador Configuration Details

index.html Structure

DOCTYPE html>
html lang="ja">
  head>
    meta charset="utf-8" />
    meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    title>Miradortitle>
    link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" />
  head>
  body>
    div id="mirador" style="position: absolute; top: 0; bottom: 0; left: 0; right: 0">div>
    script src="https://unpkg.com/mirador@latest/dist/mirador.min.js">script>
    script>
      // Configuration script
    script>
  body>
html>

Parsing URL Parameters

var vars = {};
var param = location.search.substring(1).split("&");
for (var i = 0; i  param.length; i++) {
  var keySearch = param[i].search(/=/);
  var key = "";
  if (keySearch != -1) key = param[i].slice(0, keySearch);
  var val = param[i].slice(param[i].indexOf("=", 0) + 1);
  if (key != "") vars[key] = decodeURI(val);
}

Window Configuration

var windows = [];

if (vars["manifest"]) {
  var manifests = vars["manifest"];
  var array = manifests.split(";");  // Split multiple manifests by semicolon

  for (var i = 0; i  array.length; i++) {
    var manifest = decodeURIComponent(array[i]);
    var obj = {
      manifestId: manifest,
      thumbnailNavigationPosition: "far-right",  // Display thumbnails on the far right
    };
    if (vars["canvas"]) {
      obj.canvasId = vars["canvas"];  // Initial display canvas
    }
    windows.push(obj);
  }
}

Window Behavior Settings

var windowSettings = {
  allowClose: true,        // Show close button
  allowFullscreen: true,   // Show fullscreen button
}

// Annotation mode
if (vars["annotationState"]) {
  windowSettings.highlightAllAnnotations = true;
  windowSettings.sideBarOpen = true;
  windowSettings.defaultSideBarPanel = 'annotations';
}

// Embed mode: simplify UI
if (vars["embed"] === "true") {
  windowSettings.allowClose = false;
  windowSettings.allowMaximize = false;
}

Workspace Control Panel

Controls the display of the left menu (add manifests, workspace management, etc.):

var workspaceControlPanelEnabled = vars["embed"] !== "true";
  • Normal mode: true (shown)
  • Embed mode: false (hidden)

Theme Settings

Mirador provides two themes, light and dark:

var isDarkMode = vars["theme"] === "dark";

Mirador.viewer({
  selectedTheme: isDarkMode ? "dark" : "light",
  // ...
});

To add a custom theme, use the themes option:

Mirador.viewer({
  selectedTheme: 'custom',
  themes: {
    custom: {
      palette: {
        type: 'dark',
        primary: {
          main: '#80104E',
        },
      },
    },
  },
});

Language Settings

var language = vars["lang"] || "ja";  // Default: Japanese

Mirador.viewer({
  language: language,
  // ...
});

Languages supported by Mirador: ar, de, en, fr, ja, lt, nl, pt-BR, vi, zh-CN, zh-TW, etc.

Complete Initialization Code

var miradorInstance = Mirador.viewer({
  id: "mirador",                              // Target DOM ID
  language: language,                         // Language
  selectedTheme: isDarkMode ? "dark" : "light", // Theme
  window: windowSettings,                     // Window settings
  windows: windows,                           // Initial windows to display
  workspaceControlPanel: {
    enabled: workspaceControlPanelEnabled,    // Left menu display
  },
});

React Component (MiradorViewer.tsx)

Dark Mode Detection

const [isDarkMode, setIsDarkMode] = useState(false)

useEffect(() => {
  const checkDarkMode = () => {
    setIsDarkMode(document.documentElement.classList.contains('dark'))
  }
  checkDarkMode()

  // Watch for class changes
  const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
      if (mutation.attributeName === 'class') {
        checkDarkMode()
      }
    })
  })
  observer.observe(document.documentElement, { attributes: true })

  return () => observer.disconnect()
}, [])

Getting Locale Settings

import { useLocale } from 'next-intl'

const locale = useLocale()  // 'ja' or 'en'

URL Generation

const miradorBasePath = process.env.NEXT_PUBLIC_MIRADOR_PATH || '/mirador/'
const miradorEmbedUrl = `${miradorBasePath}?manifest=${encodeURIComponent(manifestUrl)}&embed=true&lang=${locale}${isDarkMode ? '&theme=dark' : ''}`

iframe Embedding

Set the allow="fullscreen" and allowFullScreen attributes to enable fullscreen display:

iframe
  src={miradorEmbedUrl}
  className="w-full h-full border-0"
  title="IIIF Viewer"
  allow="fullscreen"
  allowFullScreen
/>

Environment Variables

Variable NameDescriptionDefault
NEXT_PUBLIC_MIRADOR_PATHBase path for Mirador/mirador/

Development and Production Environments

# Development (.env.local)
NEXT_PUBLIC_MIRADOR_PATH=/mirador/index.html

# Production (default)
# NEXT_PUBLIC_MIRADOR_PATH=/mirador/