Shoji

Settings

Every option lives in one flat GalleryOptions object, passed to new Shoji(el, options) or gallery.reinit(options). Everything below is optional — a bare new Shoji('#gallery') is a complete, working integration.

new Shoji('#gallery', {
  loop: false,
  autoHideDelay: 3000,
  plugins: [Shoji.Zoom],
});

Core options

Option Default What it does
selector ':scope > a, :scope > [data-shoji-src], :scope > [data-shoji-video]' Which direct children to scan in selector mode.
items — Opts into dynamic mode instead of scanning the DOM.
index 0 open()'s default argument, and — with openOnInit — the index opened automatically.
openOnInit false Opens immediately at construction instead of waiting for a click/open() call — for hash/deep-link-style integrations. Everyone else should leave this off.
locale English strings Flat key map — every user-visible string goes through it, no hardcoded English in the UI.
plugins [] Official or custom plugins to load, in order. See the Plugins guide.
autoHideDelay 5000

ms of inactivity before controls fade.

  • Positive number (default) — normal auto-hide.
  • 0 — hidden immediately and permanently, even with activity. Cursor stays visible (Theming guide).
  • false — always visible; controls never auto-hide, including from hideControls().
maxPinnedToolbarButtons 2 The most ctx.ui.toolbar('right', ...)-registered plugin buttons (in registration order) that stay pinned directly on the toolbar row once it doesn't fit — a ceiling, not a guarantee. If even that many would still wrap the row (e.g. a wide counter leaves less room than usual), more collapse into the popover until it fits, down to zero if it must; the counter and closeButton never wrap. The rest collapse into an overflow popover behind a caret, latest-registered first. closeButton and the caret itself are always on the row regardless; a host with more toolbar plugins than the default fits might raise this. See the Plugins guide.
preload 1 Slides kept mounted and proactively decoded on each side of the active one — navigating within that window shows instantly, no spinner. Higher values trade more memory/decoding for a bigger always-instant window.
counter true Shows the "N / M" badge. Purely visual — the live-region a11y announcement always includes position regardless.
showVideoCaption false A video slide's caption starts hidden either way — a toolbar toggle button lets the viewer show it on demand, so the caption never sits over the video's native controls unless they ask for it. true only flips the starting point to shown. Has no effect on a photo slide's caption, which is always shown.
loop true next()/prev() wrap past the ends instead of stopping. Doesn't affect goTo() with an explicit index (still clamps) or Home/End.
closable true false disables every viewer-facing way to close the lightbox — the close button (hidden entirely), backdrop click, Escape, and vertical swipe-to-close — for an embed meant to stay open permanently once shown. gallery.close() itself still works.
backdropOpacity — 0-1, clamped — real alpha: 1 is genuinely fully opaque, 0 fully transparent. Sets --shoji-backdrop-opacity (Theming guide) directly, without needing to know or override the full --shoji-color-backdrop value. Left unset, that custom property's own default (1, both themes) is untouched, so theming it directly in CSS still works.
gestures { lockThreshold: 10, swipeThreshold: 50, swipeVelocity: 0.3 } Overrides for the gesture engine's direction-lock/swipe-completion thresholds (px / px / px-per-ms). Partial — any field left out keeps its default. Momentum easing isn't configurable here; it's the CSS custom property --shoji-momentum-easing (Theming guide).
mode 'slide' The slide-to-slide transition for programmatic navigation. Full preset list and custom-CSS-transition support on the Transitions guide.
transitionDuration 300 (ms) Sets the CSS custom property --shoji-duration for you — same idea as backdropOpacity above. Leave unset to theme it directly in CSS instead; see the Transitions guide.

Clicking the toolbar's empty space (not a button) on a YouTube/provider-video slide never closes the gallery — it always has a reserved gap above the video, so a click there just brings back hidden controls.

On a photo or HTML5 video slide, it depends on the photo/video's shape. If it doesn't reach the top of the dialog (common), clicking the toolbar's empty space there closes the gallery, same as clicking anywhere else outside the content.

Plugin options

Each plugin's own options nest under a key matching its name — zoom: {...} for Shoji.Zoom, and so on (the options[plugin.name] convention). Quick reference; see the Plugins guide for the full loading contract and the Layout guide for that plugin's much larger option set.

Key Options (defaults)
zoom maxScale (4), doubleTapScale (2), buttonStep (1.5), mouseWheelZoom (true / 'ctrl' / false, default true)
fullscreen none
rotateFlip none
autoplay interval (5000ms), showProgress (true), autoStart (false), onZoom ('stop'), onRotateFlip ('stop'), onCaptionExpand ('stop'), stopOnManualNavigate (true)
activeThumbnail activeClass ('shoji-thumb-active'), scrollIntoView (true), highlight (false), borderColor ('blue'), highlightDuration (ms, unset), highlightFadeDuration (ms, 800)
layout See the dedicated guide — type, gutter/column/row sizing, groupBy/headings, breakpoints, and more.