Appearance
When manuscripts misbehave in a IIIF viewer the cause is nearly always in the manifest, not the images. The three faults that account for most support tickets are: canvases in the wrong sequence (string-sorted filenames), a missing or misplaced viewingDirection/behavior, and a Presentation API version mismatch between what your manifest declares and what the viewer expects. Fix those and 90% of manuscript display problems disappear.
Why are my pages in the wrong order?
The manifest's top-level items array is the single source of truth for page order. If pages appear as 1, 10, 11, 2, 3, your build script sorted filenames lexically. Sort numerically before emitting the manifest:
python
import re
def folio_key(name):
n = re.search(r"(\d+)", name)
return int(n.group(1)) if n else 0
pages = sorted(image_ids, key=folio_key)Re-validate after fixing: the IIIF Presentation validator will not catch a wrong order, only a wrong shape, so a visual check in Mirador remains mandatory.
How do I get facing-page spreads and reading direction right?
Manuscripts open as two-page spreads and many read right-to-left. Both are manifest-level declarations in Presentation API 3:
json
{
"@context": "http://iiif.io/api/presentation/3/context.json",
"id": "https://example.org/iiif/ms-123/manifest",
"type": "Manifest",
"viewingDirection": "right-to-left",
"behavior": ["paged"],
"label": { "en": ["Book of Hours, MS 123"] }
}behavior: ["paged"] tells the viewer to pair facing canvases; viewingDirection: "right-to-left" flips the navigation for Hebrew, Arabic and Syriac codices. Putting either property on an individual canvas is silently ignored — a common and maddening mistake.
How should foliation and structure be encoded?
Keep two concerns separate:
| Concern | IIIF mechanism | Example value |
|---|---|---|
| Folio reference of one leaf | Canvas label | 1r, 1v, 2r |
| Grouping leaves into texts/quires | structures range | "Quire 3 (ff. 17–24)" |
| Missing/damaged leaf | Canvas with placeholder | label wanting |
A clickable table of contents requires a structures array of Range objects, each listing the canvas IDs it covers. Do not abuse labels to fake a hierarchy; ranges are what viewers render as a navigable tree.
Why does one viewer work and another shows blank pages?
This is almost always a version mismatch. Presentation API 2 used @id, @type, sequences and images; version 3 uses id, type, items and AnnotationPage. Mixing them produces a manifest that one viewer tolerates and another rejects. Diagnose quickly:
bash
curl -s https://example.org/iiif/ms-123/manifest | \
python -c "import sys,json;m=json.load(sys.stdin);print(m['@context'])"If the context says presentation/3 but the body still has sequences, that is your bug. Regenerate cleanly against one version.
What about colour and damaged-leaf presentation?
Manuscript scholars zoom hard, so serve a pyramidal master and a colour target. For a leaf that is physically missing, still emit a canvas to preserve foliation arithmetic — annotate it with a placeholder and the label wanting. Skipping the canvas throws off every "folio 12 of 88" counter downstream.
A fast diagnostic order of operations
- Open the manifest URL directly in a browser — does valid JSON return, with 200 and CORS headers?
- Run it through the IIIF Presentation validator for structural errors.
- Load in Mirador and Universal Viewer; differing behaviour signals a version issue.
- Check page order, then
behavior/viewingDirection, thenstructures. - Only then suspect the image server.
Key Takeaways
- Page-order bugs come from string-sorted filenames; sort by extracted folio number.
behavior: ["paged"]andviewingDirectionare manifest-level — never per-canvas.- Use canvas
labelfor foliation andstructuresranges for the table of contents. - Keep a canvas for missing leaves so foliation counts stay correct.
- Blank pages in one viewer usually mean a Presentation v2/v3 property mismatch.
- Validate structurally, then always eyeball the result in a real viewer.
Frequently Asked Questions
Why do my manuscript pages appear in the wrong order in Mirador?
The order of the canvases in the manifest's items array is authoritative. Mirador renders exactly that sequence, so a wrong order means your manifest build script sorted filenames as strings (page10 before page2) rather than numerically.
How do I show a two-page opening as a spread?
Set the manifest's behavior to paged and viewingDirection appropriately (left-to-right or right-to-left). Viewers then pair facing canvases automatically; do not stitch two pages into one image.
Should foliation use label or a structure?
Put the human folio reference (1r, 1v, 2r) in each canvas label. Use a structures range only when you need a clickable table of contents grouping several leaves into quires or texts.
Why is the right-to-left reading direction ignored?
viewingDirection must sit at the manifest level and be a valid value such as right-to-left. A typo or placing it on a canvas silently falls back to left-to-right.
How do I present a damaged or missing leaf?
Include a canvas for the missing leaf with a placeholder image or no painting annotation and a label such as wanting. This preserves correct foliation and pagination counts.
Why does Universal Viewer show a blank page but Mirador works?
Almost always a IIIF Presentation version mismatch. Confirm your manifest declares the right context and that both viewers support that version; mixing v2 and v3 properties is the usual culprit.