Skip to content

Embedding in Publications ​

Embed an interactive OME-ZARR viewer in any web page with two lines of HTML. Designed for journals, data portals, and institutional repositories.

Two Lines of HTML to View Microscopy Data on Any Web Page explains the gap this fills. Browser-based OME-ZARR viewing is largely a solved problem, but every existing solution assumes the viewer is the page, which is no use when the page is your article.

From a View to an Embed ​

Set up the view in the viewer: position, zoom, channels, contrast, inversion, the frame you want. Then press Embed in the toolbar, the angle-brackets button next to Link.

The right-hand toolbar group with the Embed button outlined, between the Link button and the theme toggle

The dialog shows the same view as an HTML element and as a MyST directive, ready to copy. For a time-lapse it offers an autoplay checkbox. Width and height are yours to edit afterwards.

The Embed this view dialog on the MyST tab, showing an any:bundle directive with url, t, z, channels, x, y, zoom, autoplay and fps, the autoplay checkbox ticked, and Close and Copy buttons

Quick Start ​

Add the script once in your page <head>, then place the viewer element anywhere in your content:

html
<!-- Load once in <head> -->
<script src="https://find-nuclei.github.io/embed/v1/viewer.js"></script>

<!-- Place anywhere in your article -->
<find-nuclei-viewer
  url="https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.4/idr0062A/6001240.zarr"
  labels="on"
  width="100%"
  height="500"
></find-nuclei-viewer>

Try it. This is a live viewer:

Pan, zoom, toggle channels, adjust intensity. All interactive. That's it. No build step, no npm, no framework required.

Attribute Reference ​

AttributeRequiredDefaultDescription
urlYesnoneZARR store URL (HTTP or S3)
zNo0Initial Z-slice index
tNo0Initial timepoint index
channelsNoautoChannel config (see below)
xNocenterInitial X position (pixels)
yNocenterInitial Y position (pixels)
zoomNofitInitial zoom level (0 = 1:1, negative = zoomed out)
widthNo100%CSS width
heightNoauto (16:9)CSS height
labelsNooff"on" to enable all label overlays, or a label name
imageNo"0"Image/series index for multi-image ZARR stores
backgroundNoblackCanvas background color (black, white, or any CSS color)
controlsNominimal"minimal", "full", or "none"
tokenNononeBearer token for authenticated sources
themeNodark"dark" or "light"
grayscaleNooffRender every channel in grey. The viewer's BW toggle. Presence alone means on.
invertNooffInvert the composite. The viewer's INV toggle. Pair with background="white".
autoplayNooffStart time-lapse playback once the image has loaded. Presence alone means on.
fpsNo4Playback frame rate, clamped to 1..30.

Channel Configuration ​

The channels attribute uses a compact string format:

index:on/off:hexcolor:min:max

Multiple channels are comma-separated:

html
<find-nuclei-viewer
  url="https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.4/idr0079A/idr0079_images.zarr"
  channels="0:on:00FF00:8:90,1:on:FF0000:7:80"
></find-nuclei-viewer>

Live: green (lynEGFP) and red (NLStdTomato) channels with custom intensity ranges:

If omitted, channels are auto-detected from the OME-ZARR metadata.

Setting the Initial View ​

Use x, y, and zoom to point the reader at a specific region of interest:

html
<find-nuclei-viewer
  url="https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.4/idr0079A/idr0079_images.zarr"
  x="500" y="350" zoom="-0.5"
  labels="on"
  width="100%"
  height="350"
></find-nuclei-viewer>

Live: zoomed into the center of the zebrafish embryo with labels enabled:

Finding coordinates

Open the image in the viewer, navigate to the region you want, then check the URL. It contains zm (zoom) and xy (center) parameters you can copy.

Showing Segmentation Labels ​

If the ZARR dataset contains label images (segmentation masks), enable them with labels="on". Each segmented object gets a unique color. The controls panel includes a label toggle and opacity slider.

html
<find-nuclei-viewer
  url="https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.4/idr0062A/6001240.zarr"
  labels="on"
></find-nuclei-viewer>

See the first example at the top of this page for a live demo with labels.

RGB Images ​

For RGB brightfield images, set a white background:

html
<find-nuclei-viewer
  url="https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.4/idr0073A/9798462.zarr"
  background="white"
  width="100%"
  height="350"
></find-nuclei-viewer>

Live: RGB zebrafish brain section with white background and unified brightness slider:

The viewer auto-detects RGB data and shows a unified brightness slider instead of per-channel controls.

Multi-Image Stores ​

A store written by bioformats2raw can hold several images, one per series. The image attribute picks the one to show; the value is the series path, usually "0", "1" and so on. Leave it out to show the first.

html
<find-nuclei-viewer
  url="https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.4/idr0079A/idr0079_images.zarr"
  image="1"
  width="100%"
  height="400"
></find-nuclei-viewer>

The embed loads only the series it shows. An image value the store does not have falls back to the first series rather than failing.

Grayscale and Inverted Views ​

The viewer has BW and INV toggles. The embed exposes them as attributes, so a view you set up with the share link can be reproduced in an article. Inverted single-channel on white reads like a printed figure:

html
<find-nuclei-viewer
  url="https://nyu1.osn.mghpcc.org/barkley-replication/nuclei_mosaic.zarr"
  channels="0:on:FFFFFF:0:240"
  invert background="white"
  width="100%"
  height="400"
></find-nuclei-viewer>

Both attributes are boolean: present means on, and "off" or "false" means off.

MyST, Curvenote and Shadow DOM ​

MyST sites, including journals on Curvenote such as Elemental Microscopy, render widgets inside a shadow root. The element mounts there directly, but a page-level <script> tag is not available in a MyST article, so use the widget module through the any:bundle directive. Every JSON key becomes an attribute of the viewer:

markdown
:::{any:bundle} https://find-nuclei.github.io/embed/v1/widget.mjs
{
  "url": "https://your-bucket/image.zarr",
  "channels": "0:on:FFFFFF:0:240",
  "x": 2115, "y": 1688, "zoom": -1.9,
  "height": "500"
}
:::

The module loads the same /embed/v1/viewer.js release as the script tag and follows the anywidget contract, so it also works as a Jupyter widget bundle. If your platform allows neither scripts nor widgets, MyST's iframe directive pointing at a page that hosts the viewer is the fallback. A live comparison of the three routes: MyST and Shadow DOM.

Time-lapse Figures ​

In the viewer, a time-lapse gets a Play button under the time slider, and Space toggles it. Drag the slider to stop.

The Navigation panel for an 18-frame time-lapse: the Z-slice and T-timepoint sliders with a Play button beneath them

An image with a time axis gets a play button in the bottom bar. Add autoplay and the figure moves as soon as it is on screen, like an animated GIF, and pauses while scrolled out of view. Each frame is shown complete, so on a slow link the tempo drops rather than the frame tearing. fps sets the rate.

html
<find-nuclei-viewer
  url="https://nyu1.osn.mghpcc.org/barkley-replication/video.zarr"
  autoplay fps="4"
  width="100%"
  height="500"
></find-nuclei-viewer>

In a MyST article the same two keys go into the any:bundle JSON: "autoplay": true, "fps": 4. The viewer plays with Space, or the Play button under the time slider.

Multiple Viewers on One Page ​

You can embed multiple viewers on the same page. Each is independent. Viewers use lazy loading. They only fetch data when scrolled into the viewport.

WebGL Context Limits

Browsers allow ~8–16 WebGL contexts per page. If you embed more than 8 viewers, some may fail to render. The lazy loading behavior (default) helps mitigate this.

Interactive Controls ​

The embedded viewer provides these interactive controls:

  • Channel dots: Click to toggle channels on/off
  • Channel name ▾: Click to open a color picker (12 scientific color presets)
  • Intensity sliders: Dual-thumb range sliders per channel (min/max)
  • Z-slider: Navigate through Z-slices (if multi-Z)
  • T-slider: Navigate through timepoints (if time series)
  • Labels toggle: Show/hide segmentation overlays with opacity control
  • Fullscreen: Expand the viewer to fill the screen
  • "Open in Find Nuclei Viewer": Link to the full app with the same view

JavaScript API ​

For programmatic control from your page:

js
const viewer = document.querySelector('find-nuclei-viewer');

// Navigate
viewer.viewer.setZ(10);
viewer.viewer.panTo(500, 300, true);
viewer.viewer.zoomTo(-1, true);

// Change channels
viewer.viewer.updateChannelSettings(0, 100, 3000, true, '00FF00');

// Listen to events
viewer.viewer.on('z-changed', (data) => {
  console.log('Z-slice:', data.z);
});

Style Isolation ​

The embed uses Shadow DOM for complete style isolation. Your page CSS cannot break the viewer, and the viewer CSS cannot affect your page. This is safe to use in any CMS.

More Examples ​

See the Publications Demo for a full showcase with four IDR studies.

CDN & Versioning ​

The embed script is served from:

https://find-nuclei.github.io/embed/v1/viewer.js

The /v1/ path is versioned. Future breaking changes will use /v2/, so existing embeds continue to work.

Free. Private. Browser-based.