This article is co-authored with a generative AI. Facts have been cross-checked against official documentation where possible, but errors may remain. Please verify against primary sources before making any important decisions.

In Mirador, if you zoom into an image and then move to the next page, the previous page's zoom level and pan position carry over. Sometimes you want "go back to fit-the-whole-page when I change pages," so I looked into whether this is the default and whether it can be changed. Here are the verified facts and the fix.

The osdConfig.preserveViewport setting

Whether the viewport (zoom level and pan position) is carried over on page change is controlled by preserveViewport.

  • true: keep the zoom level and pan position when switching canvases (if you were zoomed in on the previous page, the next page stays at the same zoom)
  • false: fit the whole new canvas on every canvas switch (reset to the "home" view)

The easy mistake here is where it goes. preserveViewport is not a Mirador window setting; it lives in the osdConfig block (the OpenSeadragon config). Mirador's own defaults define it under osdConfig too (putting it under window has no effect).

const config = {
  id: 'viewer',
  windows: [{ manifestId: 'https://example.org/manifest.json' }],
  osdConfig: {
    // ...
    preserveViewport: false, // reset zoom/pan on page change
  },
};
Mirador.viewer(config);

Tracing the actual mechanism in Mirador v4.0.0 source: the page-change action setCanvas reads getConfig(state).osdConfig.preserveViewport, and when it is false the reducer resets the viewport state.

// src/state/actions/canvas.js (excerpt)
const { preserveViewport } = getConfig(state).osdConfig;
// → dispatches SET_CANVAS carrying preserveViewport

// src/state/reducers/viewers.js (excerpt)
case ActionTypes.SET_CANVAS:
  if (!action.preserveViewport) {
    return set([action.windowId], null, state); // drop saved zoom/pan → next page fits
  }
  return state;                                  // preserve

So it is passed via osdConfig, but it takes effect not through OpenSeadragon's sequenceMode — rather, Mirador itself reads this flag on page change and keeps or drops the viewport state (Mirador does not use sequenceMode). The image rendering itself is OpenSeadragon-based.

Defaults: true from 3.3.0 through 4.0.0, false on main

To confirm whether "carrying over" is the default, I checked the default in src/config/settings.js per release.

VersionpreserveViewport default
3.3.0true
3.4.0true
3.4.3true
4.0.0true
main (unreleased)false

So carrying over (true) has long been the default — it did not flip between v3 and v4 (I initially assumed v3 was false, but checking proved that wrong). Meanwhile the unreleased main has changed it to false, so a future release may flip the default.

You can verify this yourself from GitHub raw and the package CDN.

# Which version does mirador@latest currently resolve to (unpkg redirect target)?
curl -sI "https://unpkg.com/mirador@latest/dist/mirador.min.js" | grep -i '^location'
# → location: /mirador@4.0.0/dist/mirador.min.js

# Default per tag
curl -s "https://raw.githubusercontent.com/ProjectMirador/mirador/v4.0.0/src/config/settings.js" \
  | grep -n preserveViewport
# → 548:    preserveViewport: true,

Which one to choose

  • For items where similarly sized pages run in sequence (book spreads, etc.), true (carry over) can be pleasant — you keep reading while staying zoomed in.
  • When canvas sizes vary from page to page, false (reset) is more natural. For example, large scanned images interleaved with fixed-size images of different dimensions (a swap-in placeholder, or a separate item at a different resolution). With true, moving from a zoomed-in large image to a small one leaves you looking at just a cropped part of it.

My case was the latter — large images interleaved with a fixed 1000×1414 image — so I set preserveViewport: false explicitly to fit the whole canvas on each page.

Pitfall: mirador@latest moves the default behavior, too

The viewer was loading mirador@latest from a CDN. As shown above, @latest currently resolves to 4.0.0, but a floating version spec silently pulls in major upgrades. On top of that, the default value itself is something that can change (as main shows).

The fix is simple.

  1. Pin the version (e.g. mirador@4.0.0; align the CSS to the same version)
  2. State the behavior you depend on explicitly instead of relying on the default (here, write preserveViewport as true / false explicitly)

That keeps the viewer's behavior fixed across CDN updates or future default changes.

Wrap-up

  • Mirador carrying the zoom across pages is the behavior of preserveViewport's default (true). Set it to false to fit the whole page (reset) on each page. Put it under osdConfig, not window.
  • The default has been true consistently from 3.3.0 through 4.0.0; only the unreleased main has false, which may flip a future release.
  • false is the natural choice when canvas sizes vary per page.
  • mirador@latest moves the default behavior under you, so stabilize it with a pinned version plus an explicit setting.