Viewers Documentation

OHIF zero-footprint DICOM viewer and oncology specific Lesion Tracker, plus shared extension packages

RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy Viewers on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name viewers --restart always ohif/viewers:latest

Technical Documentation: OHIF/Viewers

ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference

Overview (README.md)


NPM version
MIT License
[

Measurement Tracking Demo
Labelmap Segmentations Demo
Fusion and Custom Hanging protocols Demo
Volume Rendering Demo
PDF Demo
RT STRUCT Demo
4D Demo
Video Demo
Slide Microscopy Demo
ECG Waveform Demo

About

The OHIF Viewer can retrieve
and load images from most sources and formats, render sets in 2D, 3D, and
reconstructed representations; allows for the manipulation, annotation, and
serialization of observations; supports internationalization, OpenID Connect,
offline use, hotkeys, and many more features.

Almost everything offers some degree of customization and configuration. If it
doesn't support something you need, we accept pull requests and have an ever
improving Extension System.

Why Choose Us

Community & Experience

The OHIF Viewer is a collaborative effort that has served as the basis for many
active, production, and FDA Cleared medical imaging viewers. It benefits from
our extensive community's collective experience, and from the sponsored
contributions of individuals, research groups, and commercial organizations.

Built to Adapt

After more than 8-years of integrating with many companies and organizations,
The OHIF Viewer has been rebuilt from the ground up to better address the
varying workflow and configuration needs of its many users. All of the Viewer's
core features are built using its own extension system. The same extensibility
that allows us to offer:

  • 2D and 3D medical image viewing
  • Multiplanar Reconstruction (MPR)
  • Maximum Intensity Project (MIP)
  • Whole slide microscopy viewing
  • PDF and Dicom Structured Report rendering
  • Segmentation rendering as labelmaps and contours
  • User Access Control (UAC)
  • Context specific toolbar and side panel content
  • and many others

Can be leveraged by you to customize the viewer for your workflow, and to add
any new functionality you may need (and wish to maintain privately without
forking).

Support

For commercial support, academic collaborations, and answers to common
questions; please use Get Support to contact
us.

Developing

Branches

`master` branch - The latest dev (beta) release

  • master - The latest dev release

This is typically where the latest development happens. Code that is in the master branch has passed code reviews and automated tests, but it may not be deemed ready for production. This branch usually contains the most recent changes and features being worked on by the development team. It's often the starting point for creating feature branches (where new features are developed) and hotfix branches (for urgent fixes).

Each package is tagged with beta version numbers, and published to npm such as @ohif/[email protected]

`release/*` branches - The latest stable releases

Once the master branch code reaches a stable, release-ready state, we conduct a comprehensive code review and QA testing. Upon approval, we create a new release branch from master. These branches represent the latest stable version considered ready for production.

For example, release/3.5 is the branch for version 3.5.0, and release/3.6 is for version 3.6.0. After each release, we wait a few days to ensure no critical bugs. If any are found, we fix them in the release branch and create a new release with a minor version bump, e.g., 3.5.1 in the release/3.5 branch.

Each package is tagged with version numbers and published to npm, such as @ohif/[email protected]. Note that master is always ahead of the release branch. We publish docker builds for both beta and stable releases.

Here is a schematic representation of our development workflow:

Requirements

  • Yarn 1.20.0+
  • Node 18+
  • Yarn Workspaces should be enabled on your machine:
    • yarn config set workspaces-experimental true

Getting Started

  1. Fork this repository
  2. Clone your forked repository
    • git clone https://github.com/YOUR-USERNAME/Viewers.git
  3. Navigate to the cloned project's directory
  4. Add this repo as a remote named upstream
    • git remote add upstream https://github.com/OHIF/Viewers.git
  5. yarn install --frozen-lockfile to restore dependencies and link projects

:::danger
In general run yarn install with the --frozen-lockfile flag to help avoid
supply chain attacks by enforcing reproducible dependencies. That is, if the
yarn.lock file is clean and does NOT reference compromised packages, then
no compromised packages should land on your machine by using this flag.
:::

To Develop

From this repository's root directory:

bash
# Enable Yarn Workspaces
yarn config set workspaces-experimental true

# Restore dependencies
yarn install --frozen-lockfile

Cornerstone3D Integration Testing

OHIF's Playwright end-to-end tests can run against a CS3D branch or a
published CS3D version, allowing changes that span both repositories to be
validated together before merging.

Setting up an integration build

Add a CS3D_REF: line to the PR body. No label is involved — the line itself is
the request.

The line must sit at the top level of the body. A line inside a fenced code
block, inside an indented code block (four spaces or more), or inside an HTML
comment is an example rather than a request, so you can document this syntax in
a PR without triggering it. The PR template is mostly HTML comments, so write
the line outside them. The workflow prints a warning when it ignores a
CS3D_REF: line for one of these reasons, and it fails when the block that
hides the line is never closed.

text
CS3D_REF: feat/my-feature

The line takes one of three forms:

Form Meaning
CS3D_REF: feat/my-feature A branch or tag in cornerstonejs/cornerstone3D. The workflow clones it, builds CS3D from source with pnpm run build:esm, and symlinks the built packages into OHIF's node_modules.
CS3D_REF: 5.10.6 A published version. The workflow rewrites every @cornerstonejs/* entry across the workspace to that version and reinstalls. The accepted forms are 5.10.6, 5.11.0-beta.1, 5.x, 5.10.x and 4.19+. A two-part number such as 5.10 is not one of them; write 5.10.x.
CS3D_REF: feat/my-feature now 5.10.6 The branch, and the concrete release it became. See Retiring a branch ref below.

Three rules are worth knowing:

  • The branch must live in cornerstonejs/cornerstone3D. The
    <owner>: form is no longer accepted: it let a PR point the clone at
    any GitHub account and run that account's install scripts on the shared
    self-hosted runner. Push your branch to the CS3D repository instead.
  • There is no default. A PR with no CS3D_REF line runs the ordinary
    Playwright suite against the CS3D version this repo already pins. The same
    holds for a manual run with an empty cs3d_ref box.
  • From a fork, an integration run needs approval. The run waits on the
    cs3d-integration environment until one of the named reviewers approves that
    specific run, because it builds and executes CS3D code on a shared machine.
    A PR from a branch in this repository proceeds unattended.

The workflow can also be triggered manually via workflow_dispatch with a
cs3d_ref input, which accepts the same three forms.

What happens in CI

The Playwright workflow runs three jobs:

Job Purpose
Gate Runs on GitHub's own runners and never checks out the repository. It decides whether the PR may reach the self-hosted runner at all, reads and validates any CS3D_REF line, and decides whether the run needs a reviewer's approval.
Playwright Tests Builds OHIF (with CS3D linked or version-swapped), runs the full Playwright suite, and uploads test results and coverage. When a CS3D_REF line changes the tree under test, it also deploys a Netlify preview.
CS3D Branch Merge Guard Reports when CS3D_REF names a branch rather than a published version, because merging would leave master depending on unreleased CS3D code. It is advisory: it reports a red result, but it does not block the merge button.

Playwright does not run on every fork PR

A PR from a fork that changes a CI-defining file does not run Playwright on the
self-hosted runner. It runs once the change is reviewed and merged. The affected
paths are .github/, .scripts/, pnpm-workspace.yaml, preinstall.js, any
root pnpmfile, and every .npmrc in the workspace, not only the one in the
root directory.

package.json and pnpm-lock.yaml are not on the list, so a fork PR that adds
a dependency or moves a module between workspace packages runs Playwright as
usual. Changes to the root package.json and pnpm-lock.yaml still need a code
owner's review before merge. A PR from a branch in this repository is not
affected by either rule.

Testing changes that span both repos

If a feature requires changes in both Cornerstone3D and OHIF:

  1. Create your feature branch in the cornerstonejs/cornerstone3D repository and
    push it.
  2. Create a matching branch in OHIF.
  3. In the PR body, add: CS3D_REF: <your-cs3d-branch>.
  4. Playwright tests build CS3D from source, link it, and run the full suite. The
    merge guard reports a red result for as long as the line names a branch, so
    you can see the test results and the preview deploy while you iterate.
  5. Once the CS3D side is merged and published, change the line to the retiring
    form below.

Retiring a branch ref

Once the CS3D fix ships, change the line rather than deleting it:

text
CS3D_REF: feat/my-feature now 5.10.6

The version after now is a record, not a request. It never moves the pin
backwards: on every run the workflow compares it against the version this repo
pins and keeps whichever is newer. So a line still saying now 5.10.6 in a repo
that has moved on to 5.11.0 tests 5.11.0, not 5.10.6.

That is what lets the line stay in place as history — the branch name remains
visible as the reason the pinned version moved, and the line stops changing what
the run does. Once the repo pins that version or something newer, no rewrite
happens, no reinstall happens, and no preview is built or deployed. The version
must be one concrete release, such as 5.10.6 or 5.11.0-beta.1, not a range.

A fork PR still asks for the cs3d-integration approval while the line is
present, even after the line is spent, because the gate has no checkout and
cannot tell which version the repo pins. Delete the line to stop the prompt.

Preview deploys

When a CS3D_REF line changes the tree under test, the Playwright workflow also
builds the OHIF viewer and deploys it to Netlify as a preview. This gives you a
live URL to manually test the combined CS3D + OHIF changes without running
anything locally. A spent retiring form tests the same tree as an ordinary run,
so it does not produce a preview.

For details on linking CS3D locally for development, see the
Cornerstone3D README.

Commands

These commands are available from the root directory. Each project directory
also supports a number of commands that can be found in their respective
README.md and package.json files.

Yarn Commands Description
Develop
dev Default development experience for Viewer
dev:fast Our experimental fast dev mode that uses rsbuild instead of webpack
test:unit Jest multi-project test runner; overall coverage
Deploy
build* Builds production output for our PWA Viewer

* - For more information on different builds, check out our Deploy
Docs

Which config each command uses

The dev server and the production build select a different default
configuration file when APP_CONFIG is not set explicitly:

Command Default config Data sources ?customization=
dev, dev:fast, start config/dev.js Full set Enabled
build config/default.js One demo source Disabled
  • config/dev.js is the full-featured local-development config: every data
    source is enabled, the ?customization= URL feature is turned on (via
    customizationUrlPrefixes), and it is kept at parity with the public demo
    (config/netlify.js) so customizations behave locally the same way they do on
    the demo.
  • config/netlify.js is the public demo / Netlify deploy config
    (build:viewer:ci), with the same full data-source set and ?customization=
    enabled.
  • config/default.js is a locked-down baseline and is now only the
    default for a plain production build (build with no APP_CONFIG): a single
    read-only demo data source and ?customization= off.

Any explicit APP_CONFIG overrides the default, e.g.
APP_CONFIG=config/default.js pnpm run dev or
APP_CONFIG=config/netlify.js pnpm run build.

Project

The OHIF Medical Image Viewing Platform is maintained as a
monorepo. This means that this repository, instead of containing a
single project, contains many projects. If you explore our project structure,
you'll see the following:

text
/* Detailed source-code truncated for AI context efficiency. */

Acknowledgments

To acknowledge the OHIF Viewer in an academic publication, please cite

Open Health Imaging Foundation Viewer: An Extensible Open-Source Framework
for Building Web-Based Imaging Applications to Support Cancer Research

Erik Ziegler, Trinity Urban, Danny Brown, James Petts, Steve D. Pieper, Rob
Lewis, Chris Hafey, and Gordon J. Harris

JCO Clinical Cancer Informatics, no. 4 (2020), 336-345, DOI:
10.1200/CCI.19.00131

Open-Access on Pubmed Central:
https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7259879/

or, for v1, please cite:

LesionTracker: Extensible Open-Source Zero-Footprint Web Viewer for Cancer
Imaging Research and Clinical Trials

Trinity Urban, Erik Ziegler, Rob Lewis, Chris Hafey, Cheryl Sadow, Annick D.
Van den Abbeele and Gordon J. Harris

Cancer Research, November 1 2017 (77) (21) e119-e122 DOI:
10.1158/0008-5472.CAN-17-0334

Note: If you use or find this repository helpful, please take the time to
star this repository on GitHub. This is an easy way for us to assess adoption
and it can help us obtain future funding for the project.

This work is supported primarily by the National Institutes of Health, National
Cancer Institute, Informatics Technology for Cancer Research (ITCR) program,
under a
grant to Dr. Gordon Harris at Massachusetts General Hospital (U24 CA199460).

NCI Imaging Data Commons (IDC) project supported the development of new features and bug fixes marked with "IDC:priority",
"IDC:candidate" or "IDC:collaboration". NCI Imaging Data Commons is supported by contract number 19X037Q from
Leidos Biomedical Research under Task Order HHSN26100071 from NCI. IDC Viewer is a customized version of the OHIF Viewer.

This project is tested with BrowserStack. Thank you for supporting open-source!

License

MIT © OHIF


Platform Docs README (`platform/docs/README.md`)

Website

This website is built using Docusaurus 2, a modern static website generator.

Installation

console
yarn install --frozen-lockfile

Local Development

console
yarn start

This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.

Build

console
yarn build

This command generates static content into the build directory and can be served using any static contents hosting service.

Deployment

console
GIT_USER=<Your GitHub username> USE_SSH=true yarn deploy

If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the gh-pages branch.


Platform Docs Docs README (`platform/docs/docs/README.md`)


id: Introduction slug: / sidebar_position: 1

The Open Health Imaging Foundation (OHIF) Viewer is an open source,
web-based, medical imaging platform. It aims to provide a core framework for
building complex imaging applications.

Key features:

  • Designed to load large radiology studies as quickly as possible. Retrieves
    metadata ahead of time and streams in imaging pixel data as needed.

  • Leverages Cornerstone3D for decoding,
    rendering, and annotating medical images.

  • Works out-of-the-box with Image Archives that support DICOMWeb.
    Offers a Data Source API for communicating with archives over proprietary API
    formats.

  • Provides a plugin framework for creating task-based workflow modes which can
    reuse core functionality.

  • Beautiful user interface (UI) designed with extensibility in mind. UI
    components available in a reusable component library built with React.js and
    Tailwind CSS

    text
    <a style={{
          backgroundColor: '#4042af',
          color: 'white',
          padding: '0.5rem 1rem',
          borderRadius: '0.25rem',
          textDecoration: 'none',
          ':hover': {
              backgroundColor: '#2a2b74'
          }
      }} href="https://ohif.org/news/">Subscribe to our newsletter</a>
      <a style={{
          backgroundColor: '#4042af',
          color: 'white',
          padding: '0.5rem 1rem',
          borderRadius: '0.25rem',
          textDecoration: 'none',
          ':hover': {
              backgroundColor: '#2a2b74'
          }
      }} href="./release-notes">Release Notes</a>
Measurement Tracking Demo
Labelmap Segmentations Demo
Fusion and Custom Hanging protocols Demo
Volume Rendering Demo
PDF Demo
RT STRUCT Demo
4D Demo
Video Demo
Slide Microscopy Demo

Where to next?

The Open Health Imaging Foundation intends to provide an imaging viewer
framework which can be easily extended for specific uses. If you find yourself
unable to extend the viewer for your purposes, please reach out via our GitHub
issues
. We are actively seeking feedback on ways to improve our
integration and extension points.

Check out these helpful links:

Citing OHIF

To cite the OHIF Viewer in an academic publication, please cite

Open Health Imaging Foundation Viewer: An Extensible Open-Source Framework
for Building Web-Based Imaging Applications to Support Cancer Research

Erik Ziegler, Trinity Urban, Danny Brown, James Petts, Steve D. Pieper, Rob
Lewis, Chris Hafey, and Gordon J. Harris JCO Clinical Cancer Informatics, no. 4 (2020), 336-345, DOI:
10.1200/CCI.19.00131

This article is freely available on Pubmed Central: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7259879/

or, for Lesion Tracker of OHIF v1, please cite:

LesionTracker: Extensible Open-Source Zero-Footprint Web Viewer for Cancer
Imaging Research and Clinical Trials

Trinity Urban, Erik Ziegler, Rob Lewis, Chris Hafey, Cheryl Sadow, Annick D.
Van den Abbeele and Gordon J. Harris Cancer Research, November 1 2017 (77) (21) e119-e122 DOI:
10.1158/0008-5472.CAN-17-0334

This article is freely available on Pubmed Central.
https://pubmed.ncbi.nlm.nih.gov/29092955/

Note: If you use or find this repository helpful, please take the time to
star this repository on Github. This is an easy way for us to assess adoption,
and it can help us obtain future funding for the project.

License

MIT © OHIF

 


Platform Docs Scripts README (`platform/docs/scripts/README.md`)

OHIF Viewer Documentation Scripts

This directory contains utility scripts for the OHIF Viewer documentation.

prepare-markdown-files.js

This script copies all markdown files from the docs directory (excluding api/ and assets/) to a /llm directory in the build output, making them available as static markdown files that can be accessed directly without the Docusaurus UI.

Purpose

These files are made available for easy access by LLMs and other tools that need to retrieve the raw markdown content without the surrounding Docusaurus UI elements.

Access URLs

After deployment, the markdown files can be accessed at URLs like:

  • https://docs.ohif.org/llm/platform/extensions/modules/commands.md
  • https://docs.ohif.org/llm/platform/services/ui/index.md

Implementation

The script is automatically run as part of the build:docs command and will:

  1. Find all markdown files in the /platform/docs/docs/ directory (excluding api/ and assets/)
  2. Copy them to /platform/docs/build/llm/ preserving the directory structure
  3. These files are then deployed to the website along with the rest of the built documentation

You can also run this script manually with:

bash
cd platform/docs
yarn run prepare-markdown-files

generate-llms-txt.js

This script generates a llms.txt file that follows the llms.txt specification by creating an index of all the markdown files that have been copied to the /llm directory.

Purpose

The llms.txt file provides an overview of all available documentation in a format that's optimized for use with Large Language Models (LLMs). It creates a structured index that LLMs can use to efficiently navigate and find information in the documentation.

Access URL

After deployment, the llms.txt file can be accessed at:

  • https://docs.ohif.org/llms.txt

Implementation

The script is automatically run as part of the build:docs command (after prepare-markdown-files.js) and will:

  1. Scan all the markdown files that were copied to the /llm directory
  2. Extract titles and summaries from the frontmatter of each file
  3. Organize them into sections based on their directory structure
  4. Generate a single llms.txt file in the standard format with links to all the documentation files
  5. Save the file to the build directory root so it will be accessible at the root of the website

You can also run this script manually with (after running prepare-markdown-files.js):

bash
cd platform/docs
yarn run generate-llms-txt

generate-llms-full-txt.js

This script generates an llms-full.txt file by concatenating the content of all markdown files from the /llm directory into a single giant file, similar to the approach used by bun.sh.

Purpose

The llms-full.txt file provides the complete content of all documentation in a single file, which can be useful for LLMs that need to search or reference the entire documentation at once. This approach allows for contextual understanding across multiple documentation pages.

Access URL

After deployment, the llms-full.txt file can be accessed at:

  • https://docs.ohif.org/llms-full.txt

Implementation

The script is automatically run as part of the build:docs command (after generate-llms-txt.js) and will:

  1. Scan all the markdown files that were copied to the /llm directory
  2. Remove frontmatter from each file to clean up the content
  3. Add clear section headers and source URLs for each file
  4. Concatenate all the content into a single file with proper organization by section
  5. Save the file to the build directory root so it will be accessible at the root of the website

The output file has the following structure:

  • Title and introduction for OHIF Viewer
  • Files are organized by their directory structure (e.g., platform, extensions, services)
  • Each file has a header with its title and source URL
  • Separator lines between files for clarity

You can also run this script manually with (after running prepare-markdown-files.js):

bash
cd platform/docs
yarn run generate-llms-full-txt

Platform Docs Docs Behaviours README (`platform/docs/docs/behaviours/README.md`)


id: README title: Behaviours sidebar_position: 0

Behaviours

This section documents how the system and UI actually behave — the
end-to-end behaviours that emerge from the interaction of services, extensions,
the data source, and Cornerstone3D, rather than the API of any single module.

It is the place for:

  • Observed behaviours — how a feature works today across the stack (e.g. how
    a DICOM SEG is fetched, decoded, and rendered; what the viewport does on study
    change; how measurements round-trip to SR).
  • Design proposals — proposed or in-progress changes to a behaviour, captured
    before/while they are implemented so the intent and trade-offs are recorded.
    These are clearly marked as proposals until they land.
  • Edge cases and failure modes — what happens when something is missing,
    slow, or malformed, and how the system is expected to degrade.

The goal is a durable, discoverable record of behaviour — the kind of
cross-cutting knowledge that is otherwise only in people's heads or scattered
across code comments. Prefer linking to the relevant source files (with line
references) so each behaviour doc stays anchored to the code it describes.

Index

  • Segmentation: loading a multiframe SEG as a single Part 10 instance
    — implemented, enabled by default. Prefetch the whole instance in one request
    and register it into the Cornerstone3D NATURALIZED frame registry so the
    per-frame load path (WADO-RS and WADO-URI) is served locally, while keeping the
    standard decode path unchanged. Per-frame loading is the exception — disable
    via loadMultiframeAsPart10: false (data source config or the
    cornerstone.segmentation.loadMultiframeAsPart10 customization).

  • Report dialog: where a save goes, and what the series is called
    — implemented. The three destinations of a save, the predecessorImageId
    rule that decides which loaded series the dialog offers, the four names that a
    new series starts from, and the descriptions that the viewer remembers.

Writing a new behaviour doc

  1. Add a kebab-case.md file in this directory.
  2. State whether it documents current behaviour or is a proposal.
  3. Link to the code (path:line) that implements or will implement it.
  4. Add it to the Index above.

Platform Docs Docs Deployment Index (`platform/docs/docs/deployment/index.md`)


Deployment

The OHIF Viewer can be served as a stand-alone PWA (progressive web
application
) by building and hosting a collection of static assets or be embedded in other web applications via an iframe if needed. In
either case, you will need to configure your instance of the Viewer so that it
can connect to your data source (the database or PACS that provides the data
your Viewer will display).

:::tip
Our goal is to make deployment as simple and painless as possible; however,
there is an inherent amount of complexity in configuring and deploying web
applications. If you find yourself a little lost, please don't hesitate to
reach out to for help.
:::

Deployment Scenarios

Stand-alone Viewer

Deploying the OHIF Viewer as a stand-alone web application provides many
benefits, but comes at the cost of time and complexity. Some benefits include:

Today:

  • Leverage extensions and
    modes to drop-in powerful new features
  • Add routes and customize the viewer's workflow
  • Finer control over styling and whitelabeling

In the future:

Hosted Static Assets

At the end of the day, a production OHIF Viewer instance is a collection of
HTML, CSS, JS, Font Files, and Images. We "build" those files from our
source code with configuration specific to our project. We then make those
files publicly accessible by hosting them on a Web Server.

Part 1 - Build Production Assets

"Building", or creating, the files you will need is the same regardless of the
web host you choose. You can find detailed instructions on how to configure and
build the OHIF Viewer in our
"Build for Production" guide.

Part 2 - Host Your App

There are a lot of benefits to hosting static assets over
dynamic content. You can find instructions on how to host your build's output
via one of these guides:

Drag-n-drop

Easy

Advanced

Embedded Viewer (iframe)

OHIF-v3 has deprecated deploying the viewer as an embedded viewer via a script
tag as the number of underlying libraries that run web workers are increasing for OHIF. An example of these libraries is OHIF's 3D rendering functionality that is provided by
vtk-js.

However, you can still embed the viewer using an iframe. You can utilize the iframe element to load the OHIF viewer and establish communication with it using the postMessage API if needed.
Read more about how to use the iframe here.

Data

The OHIF Viewer is able to connect to any data source that implements the DICOM
Web Standard
. DICOM Web refers to RESTful
DICOM Services -- a recently standardized set of guidelines for exchanging
medical images and imaging metadata over the internet. Not all archives fully
support it yet, but it is gaining wider adoption.

Configure Connection

If you have an existing archive and intend to host the OHIF Viewer at the same
domain name as your archive, then connecting the two is as simple as following
the steps laid out in our
Configuration Essentials Guide.

What if I don't have an imaging archive?

We provide some guidance on configuring a local image archive in our
Data Source Essentials
guide. Hosting an archive remotely is a little trickier. You can check out some
of our advanced recipes for modeled setups that may work for you.

What if I intend to host the OHIF Viewer at a different domain?

There are two important steps to making sure this setup works:

  1. Your Image Archive needs to be exposed, in some way, to the open web. This
    can be directly, or through a reverse proxy, but the Viewer needs some
    way
    to request its data.
  2. * Your Image Archive needs to have appropriate CORS (Cross-Origin Resource
    Sharing) Headers

* Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional
HTTP headers to tell a browser to let a web application running at one origin
(domain) have permission to access selected resources from a server at a
different origin. - MDN Web Docs: Web - Http - CORS

Most image archives do not provide either of these features "out of the box".
It's common to use IIS, Nginx, or Apache to route incoming requests and append
appropriate headers. You can find an example of this setup in our
Nginx + Image Archive Deployment Recipe.

What if my archive doesn't support DicomWeb?

It's possible to supply all Study data via JSON format, in the event you do not
have a DicomWeb endpoint. You can host all of the relevant files on any web
accessible server (Amazon S3, Azure Blob Storage, Local file server etc.)

This JSON is supplied via the '?url=' query parameter. It should reference an
endpoint that returns application/json formatted text.

If you do not have an API, you can simply return a text file containing the JSON
from any web server.

You tell the OHIF viewer to use JSON by using the dicomjson datasource and
appending '?url=' query to your mode's route:

e.g.
https://my-test-ohif-server/myMode/dicomjson?url=https://my-json-server/study-uid.json

The returned JSON object must contain a single root object with a 'studies'
array.

You can read more about using different data sources for mode's routes
here

Sample JSON format:

text
/* Detailed source-code truncated for AI context efficiency. */

More info on this JSON format can be found here
Issue #1500

Implementation Notes:

  1. For each instance url (dicom object) in the returned JSON, you must prefix
    the url with dicomjson: in order for the cornerstone image loader to
    retrieve it correctly. eg. https://image-server/my-image.dcm --->
    dicomjson:https://image-server/my-image.dcm
  2. The JSON format above is compatible with >= v3.7.8 of the application in V2
    version. Older versions of the viewer used a different JSON format. As of
    20/04/20 the public [https://viewer.ohif.org/] is a pre 3.0 version that does
    not support this format yet.
  3. The JSON format is case-sensitive. Please ensure you have matched casing with
    the naturalised Dicom format referenced in
    Issue #1500.

CORS Issues (Cross-Origin Resource Sharing)

If you host a JSON API or Images on a different domain from the app itself,
you will likely have CORS issues. This will also happen when testing from
Localhost and reaching out to remote servers. Even if the domain is the same,
different ports, subdomains or protocols (https vs http) will also cause CORS
errors. You will to need add a configuration on each server hosting these assets
to allow your App server origin.

For example:

Let's assume your application is hosted on https://my-ohif-server.com.

Your JSON API is hosted on https://my-json-api.aws.com

And your images are stored on Amazon S3 at https://my-s3-bucket.aws.com

When you first start your application, browsing to
https://my-ohif-server.com/myMode/dicomjson?url=https://my-json-api.aws.com/api/my-json-study-info.json,
you will likely get a CORS error in the browser console as it tries to connect
to https://my-json-api.aws.com.

Adding a setting on the JSON server to allow the CORS origin =
https://my-ohif-server.com should solve this.

Next, you will likely get a similar CORS error, as the browser tries to go to
https://my-s3-bucket.aws.com. You will need to go to the S3 bucket
configuration, and add a CORS setting to allow origin =
https://my-ohif-server.com.

Essentially, whenever the application connects to a remote resource, you will
need to add the applications url to the allowed CORS Origins on that resource.
Adding an origin similar to https://localhost:3000 will also allow for local
testing.

Securing Your Data

Coming soon

Recipes

We've included a few recipes for common deployment scenarios. There are many,
many possible configurations, so please don't feel limited to these setups.
Please feel free to suggest or contribute your own recipes.


Platform Docs Docs Development Getting Started (`platform/docs/docs/development/getting-started.md`)


Getting Started

Setup

Fork & Clone

If you intend to contribute back changes, or if you would like to pull updates
we make to the OHIF Viewer, then follow these steps:

  • Fork the OHIF/Viewers repository
  • Create a local clone of your fork
    • git clone https://github.com/YOUR-USERNAME/Viewers
  • Add OHIF/Viewers as a remote repository labeled upstream
    • Navigate to the cloned project's directory
    • git remote add upstream https://github.com/OHIF/Viewers.git

With this setup, you can now sync your fork to keep it
up-to-date with the upstream (original) repository. This is called a "Triangular
Workflow" and is common for Open Source projects. The GitHub blog has a good
graphic that illustrates this setup
.

Private

Alternatively, if you intend to use the OHIF Viewer as a starting point, and you
aren't as concerned with syncing updates, then follow these steps:

  1. Navigate to the OHIF/Viewers repository
  2. Click Clone or download, and then Download ZIP
  3. Use the contents of the .zip file as a starting point for your viewer

NOTE: It is still possible to sync changes using this approach. However,
submitting pull requests for fixes and features are best done with the
separate, forked repository setup described in "Fork & Clone"

Developing

Branches

`master` branch - The latest dev (beta) release

  • master - The latest dev release

This is typically where the latest development happens. Code that is in the master branch has passed code reviews and automated tests, but it may not be deemed ready for production. This branch usually contains the most recent changes and features being worked on by the development team. It's often the starting point for creating feature branches (where new features are developed) and hotfix branches (for urgent fixes).

Each package is tagged with beta version numbers, and published to npm such as @ohif/[email protected]

`release/*` branches - The latest stable releases

Once the master branch code reaches a stable, release-ready state, we conduct a comprehensive code review and QA testing. Upon approval, we create a new release branch from master. These branches represent the latest stable version considered ready for production.

For example, release/3.5 is the branch for version 3.5.0, and release/3.6 is for version 3.6.0. After each release, we wait a few days to ensure no critical bugs. If any are found, we fix them in the release branch and create a new release with a minor version bump, e.g., 3.5.1 in the release/3.5 branch.

Each package is tagged with version numbers and published to npm, such as @ohif/[email protected]. Note that master is always ahead of the release branch. We publish docker builds for both beta and stable releases.

Here is a schematic representation of our development workflow:

Requirements

  • Node.js & NPM
  • Yarn
  • Yarn workspaces should be enabled:
    • yarn config set workspaces-experimental true

Kick the tires

Navigate to the root of the project's directory in your terminal and run the
following commands:

bash
# Restore dependencies
yarn install --frozen-lockfile

# Start local development server
yarn run dev

:::danger
In general run yarn install with the --frozen-lockfile flag to help avoid
supply chain attacks by enforcing reproducible dependencies. That is, if the
yarn.lock file is clean and does NOT reference compromised packages, then
no compromised packages should land on your machine by using this flag.
:::

You should see the following output:

bash
@ohif/app: i 「wds」: Project is running at http://localhost:3000/
@ohif/app: i 「wds」: webpack output is served from /
@ohif/app: i 「wds」: Content not from webpack is served from D:\code\ohif\Viewers\platform\viewer
@ohif/app: i 「wds」: 404s will fallback to /index.html

# And a list of all generated files

🎉 Celebrate 🎉

Building for Production

More comprehensive guides for building and publishing can be found in our
deployment docs

bash
# Build static assets to host a PWA
yarn run build

Updating Dependencies

In general you will typically not be updating the various package.json files.
But for the case when you do, you will have to also update the various OHIF lock files
and as such you will have to do both a yarn and bun install without
the --frozen-lockfile flag.

:::danger
Updating the package.json must be done with care so as to avoid incorporating
vulnerable, third-party packages and/or versions. Please research the added
packages and/or versions for vulnerabilities.

Here is what you should do when adding new packages and/or versions prior to
committing and pushing your code:

  1. Do your due diligence researching the added packages and/or versions for vulnerabilities.
  2. Update the package.json files.
  3. Execute yarn run install:update-lockfile. This updates both the yarn.lock and
    the bun.lock files.
  4. Execute yarn run audit for a last security check. This runs both yarn audit and
    bun audit.
  5. Include both the yarn.lock and bun.lock files as part of your commit.

If any of your research or auditing for vulnerabilities find HIGH risk vulnerabilities
do NOT commit or push your changes! Low and moderate risk vulnerabilities are acceptable.
:::

Troubleshooting

  • If you receive a "No Studies Found" message and do not see your studies, try
    changing the Study Date filters to a wider range.
  • If you see a 'Loading' message which never resolves, check your browser's
    JavaScript console inside the Developer Tools to identify any errors.

Platform Docs Docs Faq Index (`platform/docs/docs/faq/index.md`)


id: index title: OHIF Viewer FAQ summary: Comprehensive list of frequently asked questions about the OHIF Viewer, covering common inquiries about reporting bugs, requesting features, academic collaborations, regulatory status, and obtaining demo studies.

General FAQ

How do I report a bug?

Navigate to our GitHub Repository, and submit a new bug report.
Follow the steps outlined in the Bug Report Template.

How can I request a new feature?

At the moment we are in the process of defining our roadmap and will do our best
to communicate this to the community. If your requested feature is on the
roadmap, then it will most likely be built at some point. If it is not, you are
welcome to build it yourself and contribute it.
If you have resources and would like to fund the development of a feature,
please contact us.

Who should I contact about Academic Collaborations?

Gordon J. Harris
at Massachusetts General Hospital is the primary contact for any academic
collaborators. We are always happy to hear about new groups interested in using
the OHIF framework, and may be able to provide development support if the
proposed collaboration has an impact on cancer research.

Does OHIF offer support?

yes, you can contact us for more information here

Does The OHIF Viewer have [510(k) Clearance][501k-clearance] from the U.S. F.D.A or [CE Marking][ce-marking] from the European Commission?

NO. The OHIF Viewer is NOT F.D.A. cleared or CE Marked. It is the users'
responsibility to ensure compliance with applicable rules and regulations. The
License for the OHIF
Platform does not prevent your company or group from seeking F.D.A. clearance
for a product built using the platform.

If you have gone this route (or are going there), please let us know because we
would be interested to hear about your experience.

Is there a DICOM Conformance Statement for the OHIF Viewer?

Yes, check it here DICOM Conformance Statement

Is The OHIF Viewer [HIPAA][hipaa-def] Compliant?

NO. The OHIF Viewer DOES NOT fulfill all of the criteria to become HIPAA
Compliant. It is the users' responsibility to ensure compliance with applicable
rules and regulations.

Could you provide me with a particular study from the OHIF Viewer Demo?

You can check out the studies that we have put in this Dropbox link


Platform Docs Docs Migration Guide Index (`platform/docs/docs/migration-guide/index.md`)


import DocCardList from '@theme/DocCardList';

Migration Guides

Based on the version you are migrating from, you can find the migration guide for the latest version of the platform.


Platform Docs Docs User Guide Index (`platform/docs/docs/user-guide/index.md`)


Study List

Overview

The first page you will see when the viewer is loaded is the Study List. In
this page you can explore all the studies that are stored on the configured
server for the OHIF Viewer.

Study Limit

To accommodate the various data sources that support various query parameters for
paging and limiting results it was decided to handle paging in the OHIF client.
This nicely handles those data sources that do not support paging and query limits.
For those that support the limit query parameter, there is a data source
configuration parameter queryLimit that will be passed for study list searches
so as to cap the result. When not specified, this value defaults to 101.

Sorting

When the Study List is opened, the application queries the PACS for 101 studies
by default. If there are greater than 100 studies returned, the default sort for
the study list is dictated by the image archive that hosts these studies for the
viewer and study list sorting will be disabled. If there are less than or equal
to 100 studies returned, they will be sorted by study date (most recent to
oldest) and study list sorting will be enabled. Whenever a query returns greater
than 100 studies, use filters to narrow results below 100 studies to enable
Study List sorting.

Filters

There are certain filters that can be used to limit the study list to the
desired criteria.

  • Patient Name: Searches between patients names
  • MRN: Searches between patients Medical Record Number
  • Study Date: Filters the date of the acquisition
  • Description: Searches between study descriptions
  • Modality: Filters the modalities
  • Accession: Searches between patients accession number

An example of using study list filter is shown below:

Below the study list are pagination options for 25, 50, or 100 studies per page.

For static wado servers, you can enable fuzzy matching by setting the supportsFuzzyMatching property to true, after enabling it, fuzzy matching will be peformed on the patient name field, for example, if PatientName is "John^Doe", then "jo", "Do" and "John Doe" will all match. However "ohn" will not match.

Study Summary

Click on a study to expand the study summary panel.

A summary of series available in the study is shown, which contains the series
description, series number, modality of the series, instances in the series, and
buttons to launch viewer modes to display the study.

Study Specific Modes

All available modes are seen in the study expanded view. Modes can be enabled or
disabled for a study based on the modalities contained within the study.

In the screenshot below, there are two modes shown for the selected study

  • Basic Viewer: Default mode that enables rendering and measurement tracking

  • PET/CT Fusion: Mode for visualizing the PET CT study in a 3x3 format.

Based on the mode configurations (e.g., available modalities), PET/CT mode is
disabled for studies that do not contain PET AND CT images.

The previous screenshot shows a study containing PET and CT images and both
Basic Viewer and PET/CT Mode are available.

View Study

The Basic Viewer mode is available for all studies by default. Click on the
mode button to launch the viewer.


Platform Docs Versioned Docs Version 3.11 README (`platform/docs/versioned_docs/version-3.11/README.md`)


id: Introduction slug: / sidebar_position: 1

The Open Health Imaging Foundation (OHIF) Viewer is an open source,
web-based, medical imaging platform. It aims to provide a core framework for
building complex imaging applications.

Key features:

  • Designed to load large radiology studies as quickly as possible. Retrieves
    metadata ahead of time and streams in imaging pixel data as needed.

  • Leverages Cornerstone3D for decoding,
    rendering, and annotating medical images.

  • Works out-of-the-box with Image Archives that support DICOMWeb.
    Offers a Data Source API for communicating with archives over proprietary API
    formats.

  • Provides a plugin framework for creating task-based workflow modes which can
    reuse core functionality.

  • Beautiful user interface (UI) designed with extensibility in mind. UI
    components available in a reusable component library built with React.js and
    Tailwind CSS

    text
    <a style={{
          backgroundColor: '#4042af',
          color: 'white',
          padding: '0.5rem 1rem',
          borderRadius: '0.25rem',
          textDecoration: 'none',
          ':hover': {
              backgroundColor: '#2a2b74'
          }
      }} href="https://ohif.org/news/">Subscribe to our newsletter</a>
      <a style={{
          backgroundColor: '#4042af',
          color: 'white',
          padding: '0.5rem 1rem',
          borderRadius: '0.25rem',
          textDecoration: 'none',
          ':hover': {
              backgroundColor: '#2a2b74'
          }
      }} href="./release-notes">Release Notes</a>
Measurement Tracking Demo
Labelmap Segmentations Demo
Fusion and Custom Hanging protocols Demo
Volume Rendering Demo
PDF Demo
RT STRUCT Demo
4D Demo
Video Demo
Slide Microscopy Demo

Where to next?

The Open Health Imaging Foundation intends to provide an imaging viewer
framework which can be easily extended for specific uses. If you find yourself
unable to extend the viewer for your purposes, please reach out via our GitHub
issues
. We are actively seeking feedback on ways to improve our
integration and extension points.

Check out these helpful links:

Citing OHIF

To cite the OHIF Viewer in an academic publication, please cite

Open Health Imaging Foundation Viewer: An Extensible Open-Source Framework
for Building Web-Based Imaging Applications to Support Cancer Research

Erik Ziegler, Trinity Urban, Danny Brown, James Petts, Steve D. Pieper, Rob
Lewis, Chris Hafey, and Gordon J. Harris JCO Clinical Cancer Informatics, no. 4 (2020), 336-345, DOI:
10.1200/CCI.19.00131

This article is freely available on Pubmed Central: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7259879/

or, for Lesion Tracker of OHIF v1, please cite:

LesionTracker: Extensible Open-Source Zero-Footprint Web Viewer for Cancer
Imaging Research and Clinical Trials

Trinity Urban, Erik Ziegler, Rob Lewis, Chris Hafey, Cheryl Sadow, Annick D.
Van den Abbeele and Gordon J. Harris Cancer Research, November 1 2017 (77) (21) e119-e122 DOI:
10.1158/0008-5472.CAN-17-0334

This article is freely available on Pubmed Central.
https://pubmed.ncbi.nlm.nih.gov/29092955/

Note: If you use or find this repository helpful, please take the time to
star this repository on Github. This is an easy way for us to assess adoption,
and it can help us obtain future funding for the project.

License

MIT © OHIF

 


Platform Docs Docs Migration Guide 3p10 To 3p11 Index (`platform/docs/docs/migration-guide/3p10-to-3p11/index.md`)


id: index sidebar_position: 1 sidebar_label: 3.10 -> 3.11 title: 3.10 to 3.11 Migration Guide

import DocCardList from '@theme/DocCardList';

3.10 to 3.11 Migration Guide

Here you can find the migration guides for upgrading from OHIF version 3.10 to version 3.11.


Platform Docs Docs Migration Guide 3p11 To 3p12 Index (`platform/docs/docs/migration-guide/3p11-to-3p12/index.md`)


Migration Guide

This guide provides information about migrating from OHIF version 3.11 to version 3.12

Optional: Migrate modes to extend `modes/basic`

There is a lot of support for the basic mode definition contained in the
modes/basic module. Using this framework will allow your mode to avoid
creating a lot of boilerplate code that may not upgrade very well.

This is an OPTIONAL change - your existing mode definitions will continue to work,
but using the new basic mode as a basis will reduce the amount of effort when
there are changes unrelated to your custom mode.

ui button with text size

Using the class text size with the ui-button is inconsistent as to whether
it will apply or not. Instead, create a new size value to assign the desired size.
To support this, a new size enum is created, smallTall, which is used in the worklist
for an over-ride.

`createReportDialogPrompt`

The create report dialog prompt (which is MOSTLY an internal component) has
change the API a bit. The input is now:

  • title shown in the dialog
  • modality being stored, used to query existing series
  • minSeriesNumber is the start of new series of this modality type.
    Will get set to 4000 if not determined by the modality
  • predecessorImageId is the image id that this series was currently loaded
    from. That allows defaulting the dialog to show the specified series instead
    of always creating a new series.

The minSeries and predecessor are both optional, so the input doesn't have to be
updated.

The output has been enhanced with:

  • series, is the series to store do, as referenced by a predecessorImageId value.
    This allows exactly specifying which item to replace, which allows selecting it in the
    menu by default instead of just guessing what value is being replaced.
  • priorSeriesNumber is the previously lowest series number at least minSeriesNumber
    of all the seris of the given modality type. This allows adding an instance to the
    next series number by adding 1 to this value.

The priorSeriesNumber will default to 4000 for an unknown modality type, or
3000 for sr, 3100 for seg and 3200 for rtstruct.

metadataProvider and formatted metadata

The metadata provider has been formatting some fields, which causes inconsistency
between different metadata providers and use of the instance object. The
specific fields that have changed are:

  • patientName
  • studyDate, studyTime
  • seriesDate, seriesTime

If these fields need formatted versions, it is recommended to add a secondary/computed
metadata provider which simply gets the base metadata module and adds the
formatting. That way different metadata providers are all handled identically.


Platform Docs Docs Migration Guide 3p12 To 3p13 Index (`platform/docs/docs/migration-guide/3p12-to-3p13/index.md`)


id: index sidebar_position: 1 sidebar_label: 3.12 -> 3.13 title: 3.12 to 3.13 Migration Guide

import DocCardList from '@theme/DocCardList';

3.12 to 3.13 Migration Guide

This guide covers changes when upgrading from OHIF version 3.12 to version 3.13.

The largest changes in 3.13 are infrastructure-level:

  • Package Manager — the monorepo moves from
    yarn + lerna to pnpm workspaces, with new install/run commands
    and a workspace:* syntax for cross-package dependencies.
  • Build Tooling — Webpack is replaced with
    Rspack v2 across the app and every extension/mode, with new
    plugin imports and faster build commands.
  • Node Version — the minimum Node.js runtime
    is now 24.
  • SegmentationService — the
    removeSegmentationRepresentations method was renamed.
  • DICOM video viewport — the
    @ohif/extension-dicom-video.viewportModule.dicom-video namespace was
    removed; route DICOM video display sets through the Cornerstone viewport.
  • Deployment recipes — the Keycloak recipes
    now require a .env file and a generated client secret before
    docker compose up, and the nginx recipes no longer send wildcard CORS
    headers (cross-origin deployments must set an explicit origin).

Platform Docs Docs Migration Guide 3p13 To 3p14 Index (`platform/docs/docs/migration-guide/3p13-to-3p14/index.md`)


id: index sidebar_position: 1 sidebar_label: 3.13 -> 3.14 title: 3.13 to 3.14 Migration Guide

import DocCardList from '@theme/DocCardList';

3.13 to 3.14 Migration Guide

This guide covers changes when upgrading from OHIF version 3.13 to version 3.14.

  • React 19 — the monorepo moves to React 19.2.7.
    @ohif/ui-next now declares react/react-dom as peerDependencies, so
    consuming applications must supply React 19, and extensions and modes require
    it too.

  • SmartScrollbar — SmartScrollbarFill and
    SmartScrollbarEndpoints now require the marked array to change identity when
    its contents change. The version prop is deprecated and no longer invalidates.

  • WorkList — LegacyWorkList and the workList.variant
    customization still work in 3.14 and are deprecated. A future release removes
    both; migrate to the workList.* customizations on the ui-next WorkList.

  • DataTable / TanStack Table v9 — @ohif/ui-next upgrades
    @tanstack/react-table to v9. Column definitions need the DataTableFeatures
    generic and the sortFn rename; programmatic visibility toggles should go
    through useToggleColumnVisibility.

  • useSegmentationExpanded — the hook
    returns undefined outside a SegmentationExpandedProvider instead of
    throwing, and no longer takes a component-name argument. Callers that wrapped
    it in try/catch should check for undefined; callers that require the
    provider should assert for themselves.

  • Viewport element hooks — useViewportRef and
    useViewportRefs are replaced by useViewportElement for readers and
    useViewportElementRegistration for the viewport that owns the element, and
    ViewportRefsProvider is renamed ViewportElementsProvider. The element is now
    a subscribed value rather than a snapshot read during render.

  • Save/report dialog — the dialog for storing
    measurements, segmentations and contours replaces its series drop down with an
    explicit choice of three destinations: Save to current, Save as new and
    Replace existing. The series number of a new series is editable, and the
    series descriptions used before are remembered per type of item and offered as
    completions. createReportDialogPrompt takes defaultSeriesDescription,
    itemType and rememberedDescriptionCount, and returns a seriesNumber. A
    stored instance is now identified like a loaded one, so the object just saved
    becomes the predecessor of the next save of the same data.

  • Display set date/time ordering — derived
    display sets are ordered by the creation date/time of the instance they show
    rather than by their series date/time, comparators registered with
    addSameSeriesCompare now actually run, instances tie-break by creation
    date/time before the SOP instance UID, and saved reports and segmentations are
    stamped with a creation date/time and an instance number.

  • useCustomization — @ohif/core adds a
    useCustomization hook. A component that calls
    customizationService.getCustomization during render can now freeze at a stale
    value, because the React Compiler caches the call on the service reference,
    which never changes. Move such reads to the hook. Event handlers and non-React
    code keep calling the service directly.

  • InputNumber — InputNumber.HorizontalControls and
    InputNumber.VerticalControls now share min, max, step and disabled
    through a nested provider rather than by writing onto the root context object.
    That fixes constraints being discarded on every keystroke, but it means only
    descendants of the controls receive them; an InputNumber.Input rendered as
    a sibling silently falls back to min=0, max=100, step=1.

  • createContext helper — the internal
    ui-next/lib/createContext helper is removed. It was never exported from
    @ohif/ui-next; if you imported it from source, use React's own
    createContext and useContext — the compiler now provides the memoization it
    was hand-rolling.


Platform Docs Docs Migration Guide 3p8 To 3p9 Index (`platform/docs/docs/migration-guide/3p8-to-3p9/index.md`)


id: 3p8-to-3p9 title: 3.8 -> 3.9 sidebar_position: 2 summary: Migration guide for upgrading from OHIF 3.8 to 3.9, covering segmentation architecture changes, renamings, data sources, measurements, viewport action corners, state sync service, RT structure improvements, UI changes, and other refactorings.

import DocCardList from '@theme/DocCardList';

Migration Guide Sections


Platform Docs Docs Migration Guide 3p9 To 3p10 Index (`platform/docs/docs/migration-guide/3p9-to-3p10/index.md`)


Migration Guide

General


Platform Docs Docs Platform Extensions Index (`platform/docs/docs/platform/extensions/index.md`)


Introduction

We have re-designed the architecture of the OHIF-v3 to enable building
applications that are easily extensible to various use cases (modes) that behind
the scene would utilize desired functionalities (extensions) to reach the goal
of the use case.

Previously, extensions were “additive” and could not easily be mixed and matched
within the same viewer for different use cases. Previous OHIF-v2 architecture
meant that any minor extension alteration usually would require the user to hard
fork. E.g. removing some tools from the toolbar of the cornerstone
extension meant you had to hard fork it, which was frustrating if the
implementation was otherwise the same as master.

  • Developers should make packages of reusable functionality as extensions,
    and can consume publicly available extensions.
  • Any conceivable radiological workflow or viewer setup will be able to be
    built with the platform through modes.

Practical examples of extensions include:

Diagram showing how extensions are configured and accessed.

Extension Skeleton

An extension is a plain JavaScript object that has id and version properties, and one or
more modules and/or lifecycle hooks.

js
// prettier-ignore
export default {
  /**
   * Required properties. Should be a unique value across all extensions.
   */
  id,

  // Lifecycle
  preRegistration() { /* */ },
  onModeEnter() { /* */ },
  onModeExit() { /* */ },
  // Modules
  getLayoutTemplateModule() { /* */ },
  getDataSourcesModule() { /* */ },
  getSopClassHandlerModule() { /* */ },
  getPanelModule() { /* */ },
  getViewportModule() { /* */ },
  getCommandsModule() { /* */ },
  getContextModule() { /* */ },
  getToolbarModule() { /* */ },
  getHangingProtocolModule() { /* */ },
  getUtilityModule() { /* */ },
}

OHIF-Maintained Extensions

A small number of powerful extensions for popular use cases are maintained by
OHIF. They're co-located in the OHIF/Viewers repository, in
the top level extensions/ directory.

Extension Description Modules
default Default extension provides default viewer layout, a study/series
text
browser, and a datasource that maps to a DICOMWeb compliant backend | commandsModule, ContextModule, DataSourceModule, HangingProtocolModule, LayoutTemplateModule, PanelModule, SOPClassHandlerModule, ToolbarModule |

| cornerstone | Provides 2d and 3d rendering functionalities | ViewportModule, CommandsModule, UtilityModule |
| dicom-pdf | Renders PDFs for a specific SopClassUID. | Viewport, SopClassHandler |
| dicom-video | Renders DICOM Video files. | Viewport, SopClassHandler |
| cornerstone-dicom-sr | Maintained extensions for cornerstone and visualization of DICOM Structured Reports | ViewportModule, CommandsModule, SOPClassHandlerModule |
| measurement-tracking | Tracking measurements in the measurement panel | ContextModule,PanelModule,ViewportModule,CommandsModule |

Registering of Extensions

viewer starts by registering all the extensions specified inside the
pluginConfig.json, by default we register all extensions in the repo.

js title=platform/app/pluginconfig.json
// Simplified version of the `pluginConfig.json` file
{
  "extensions": [
    {
      "packageName": "@ohif/extension-cornerstone",
      "version": "3.4.0"
    },
    {
      "packageName": "@ohif/extension-measurement-tracking",
      "version": "3.4.0"
    },
    // ...
  ],
  "modes": [
    {
      "packageName": "@ohif/mode-longitudinal",
      "version": "3.4.0"
    }
  ]
}

:::note
You can register extensions by editing the pluginConfig.json file directly.
The provided cli can also add/remove/install/uninstall extensions
(read more), but it is being phased out in
favour of generating extensions with an agent.
:::

For the full set of fields (packageName, version, default, directory,
the public section) and the three ways a plugin can be located (in-tree,
out-of-tree directory, or installed dependency), see the
pluginConfig.json reference.

The final registration and import of the extensions happen inside a non-tracked file pluginImport.js (this file is also for internal use only).

After an extension gets registered within the viewer,
each module defined by the extension becomes available to the modes
via the ExtensionManager by requesting it via its id.
Read more about Extension Manager

Lifecycle Hooks

Currently, there are three lifecycle hook for extensions:

preRegistration This hook is called once on
initialization of the entire viewer application, used to initialize the
extensions state, and consume user defined extension configuration. If an
extension defines the preRegistration
lifecycle hook, it is called before any modules are registered in the
ExtensionManager. It's most commonly used to wire up extensions to
services and commands, and to
bootstrap 3rd party libraries.

onModeEnter: This hook is called whenever a new
mode is entered, or a mode’s data or datasource is switched. This hook can be
used to initialize data.

onModeExit: Similarly to onModeEnter, this hook is
called when navigating away from a mode, or before a mode’s data or datasource
is changed. This can be used to cache data for reuse later, but since it
isn't known which mode will be entered next, the state after exiting should be
clean, that is, the same as the state on a clean start. This is called BEFORE
service clean up, and after mode specific onModeExit handling.

Modules

Modules are the meat of extensions, the blocks that we have been talking about
a lot. They provide "definitions", components, and filtering/mapping logic that
are then made available to modes and services.

Each module type has a special purpose, and is consumed by our viewer
differently.

Types Description
LayoutTemplate Control Layout of a route
DataSource Control the mapping from DICOM metadata to OHIF-metadata
SOPClassHandler Determines how retrieved study data is split into "DisplaySets"
Panel Adds left or right hand side panels
Viewport Adds a component responsible for rendering a "DisplaySet"
Commands Adds named commands, scoped to a context, to the CommandsManager
Toolbar Adds buttons or custom components to the toolbar
Context Shared state for a workflow or set of extension module definitions
HangingProtocol Adds hanging protocol rules
Utility Expose utility functions to the outside of extensions

Tbl. Module types
with abridged descriptions and examples. Each module links to a dedicated
documentation page.

Contexts

The @ohif/app tracks "active contexts" that extensions can use to scope
their functionality. Some example contexts being:

  • Route: ROUTE:VIEWER, ROUTE:STUDY_LIST
  • Active Viewport: ACTIVE_VIEWPORT:CORNERSTONE, ACTIVE_VIEWPORT:VTK

An extension module can use these to say "Only show this Toolbar Button if the
active viewport is a Cornerstone viewport." This helps us use the appropriate UI
and behaviors depending on the current contexts.

For example, if we have hotkey that "rotates the active viewport", each Viewport
module that supports this behavior can add a command with the same name, scoped
to the appropriate context. When the command is fired, the "active contexts"
are used to determine the appropriate implementation of the rotation behavior.


Platform Docs Docs Platform Hooks Index (`platform/docs/docs/platform/hooks/index.md`)


title: Hooks summary: List of React hooks available in the platform, these are custom hooks that are used to access the state of the platform

Hooks

[useMeasurements](./useMeasurements.md)

A React hook that provides mapped measurements from the measurement service with automatic updates when measurements change.

[useViewportSegmentations](./useViewportSegmentations.md)

A React hook that provides segmentation data and representations for the active viewport with automatic updates when segmentations change.

[useMeasurementTracking](./useMeasurementTracking.md)

A React hook that provides measurement tracking information for a specific viewport, including tracking state and tracked measurement UIDs.

[useViewportDisplaySets](./useViewportDisplaySets.md)

A React hook that provides access to display sets associated with a viewport, including background, foreground, overlay, and potential display sets.

[useViewportHover](./useViewportHover.md)

A React hook that tracks mouse hover state and active status for a specific viewport.

[usePatientInfo](./usePatientInfo.md)

A React hook that provides patient information from the active display sets and detects when multiple patients are loaded.

[useSearchParams](./useSearchParams.md)

A React hook that provides access to URL search parameters from both the query string and hash fragment.

[useDynamicMaxHeight](./useDynamicMaxHeight.md)

A React hook that calculates the maximum height for an element based on its position in the viewport, with automatic recalculation on window resize or data changes.

[useSessionStorage](./useSessionStorage.md)

A React hook that provides sessionStorage access with automatic JSON parsing/stringifying and an option to clear data when the page unloads.


Platform Docs Docs Platform Managers Index (`platform/docs/docs/platform/managers/index.md`)


Managers

Overview

OHIF uses Managers to accomplish various purposes such as registering new
services, dependency injection, and aggregating and exposing extension
features.

OHIF-v3 provides the following managers which we will discuss in depth.

Manager Description
Extension Manager Aggregating and exposing modules and features through out the app
Services Manager Single point of registration for all internal and external services
Commands Manager Register commands with specific context and run commands in the app
Hotkeys Manager For keyboard keys assignment to commands

Platform Docs Docs Platform Modes Index (`platform/docs/docs/platform/modes/index.md`)


Modes

Overview

A mode can be thought of as a viewer app configured to perform a specific task,
such as tracking measurements over time, 3D segmentation, a guided radiological
workflow, etc. Addition of modes enables application with many applications
as each mode become a mini app configuration behind the scene.

Upon initialization the viewer will consume extensions and modes and build up
the route desired, these can then be accessed via the study list, or directly
via url parameters.

OHIF-v3 architecture can be seen in the following:

Note: Templates are now a part of “extensions” Routes are configured by modes
and/or app

As mentioned, modes are tied to a specific route in the viewer, and multiple
modes/routes can be present within a single application. This allows for
tremendously more flexibility than before you can now:

  • Simultaneously host multiple viewers with for different use cases from within
    the same app deploy.
  • Make radiological viewers for specific purposes/workflows, e.g.:
    • Tracking the size of lesions over time.
    • PET/CT fusion workflows.
    • Guided review workflows optimized for a specific clinical trial.
  • Still host one single feature-rich viewer if you desire.

Anatomy

A mode configuration has a route name which is dynamically transformed into a
viewer route on initialization of the application. Modes that are available to a
study will appear in the study list.

The mode configuration specifies which extensions the mode requires, which
LayoutTemplate to use, and what props to pass to the template. For the default
template this defines which side panels will be available, as well as what
viewports and which displaySets they may hang.

Mode's config is composed of these elements:

  • id: the mode id
  • modeFactory: the function that returns the mode specific configuration
  • modeInstance: An optional configuration used by the default modeFactory
    exported by the basic mode. This allows specifying or updating the
    default mode values.
  • extensionDependencies: the list of extensions that the mode requires

that return a config object with certain
properties, the high-level view of this config object is:

js title="modes/example/src/index.js"
function modeFactory({modeConfiguration}) {
  return { ...this.modeInstance, ...modeConfiguration };

}

const mode = {
  id,
  modeFactory,
  modeInstance: {
    id: '',
    version: '',
    hide: true,
    displayName: '',
    onModeEnter: () => {},
    onModeExit: () => {},
    validationTags: {},
    isValidMode: () => {},
    routes: [
      {
        path: '',
        init: () => {},
        layoutInstance: {
          id,
          props: {
            leftPanels: [],
            leftPanelResizable: true,
            rightPanels: [],
            rightPanelClosed: true,
            rightPanelResizable: true,
            viewports: [],
          },
        },
        layoutTemplate: function() { return this.layoutInstance },
      },
    ],
    extensions: extensionDependencies,
    hangingProtocol: [],
    sopClassHandlers: [],
    hotkeys: [],
    nonModeModalities: [],
    modeModalities: [],
  },
  extensionDependencies,
};

export default mode;
Property Description
id unique mode id used to refer to the mode
hide Set to true to hide this mode on the worklist, but allow it in the path
displayName actual name of the mode being displayed for each study in the study summary panel
onModeEnter hook is called when the mode is entered by the specified route
onModeExit hook is called when the mode exited
validationTags validationTags
isValidMode Checks if the mode is valid for a study
routes route config which defines the route address, and the layout for it
extensionDependencies extensions needed by the mode
hanging protocol list of hanging protocols that the mode applies initially, choosing the highest scoring match
sopClassHandlers list of SOPClass modules needed by the mode
hotkeys hotkeys
modeModalities If non-empty, then the default isValidMode will only return true when the modalities list has all of the elements of one of the mode modalities. Eg [ [CT,PT], [MR,PT] ]` would mean that the mode supports a CT AND a PT, OR an MR and a PT
nonModeModalities Enable the mode if the modalities list contains a modality OTHER than those in the array
excludedModalities The default isValidMode returns false when the modalities list contains ANY of these
excludedStudies A list of study attribute objects; the default isValidMode returns false for a study matching every attribute of any entry, e.g. [&#123; mrn: 'M1' &#125;]
toolbarSections Toolbar section composition: a list of section-layout packs (as $reference markers) and/or literal section objects; seeded onto the Mode scope on enter
toolbarButtons Toolbar button composition: a list of button packs (as $reference markers) and/or literal button definitions; seeded onto the Mode scope on enter
toolGroupAdditions Per-tool-group composition: a map of tool-group id to a list of tool packs (as $reference markers) and/or literal tool blocks, layered onto the mode's tool groups after creation
initToolGroups Tool group setup function called by the shared onModeEnter as initToolGroups(&#123; extensionManager, toolGroupService, commandsManager, servicesManager &#125;); extending modes can substitute their own
modeCustomizations The mode's own customizations, applied by the mode route as the bottom layer of the mode scope on enter — before the app config / URL mode phase blocks, and below global-scope customizations, so final values are decided purely by scope precedence and application order. Usually the name of a block the extension registers at default scope (e.g. basicModeCustomizations, which sets panelSegmentation.disableEditing); may also be a literal object of immutability-helper commands or an array mixing those with customization module reference strings
activatePanelTriggers Data-driven ActivatePanel event triggers: a list of &#123; panelId, sourceServiceName, sourceEvents, forceActive? &#125; entries wired up on mode enter (e.g. activating the segmentation panel when a segmentation is added). Empty by default; see defaultActivatePanelTriggers in the basic mode

Extending Modes

The basic mode provides support for creating mode extensions without having
to redeclare the entire mode. See longitudinal/src/index.ts for an example
mode that builds on top of the basic mode. Also see basic/src/index.tsx for
some default functions which can be used to create your own modes. Doing a mode
this way makes the definition of new modes based on your existing mode much easier,
and the upgrade to new versions of modes tends to be more consistent.

The segmentation and tmtv modes now follow this same pattern. Like
longitudinal, each one exports a modeInstance object and reuses the basic
mode's modeFactory, so they are extensible in two complementary ways:

  1. Build a derived mode — create a new mode package (for example
    mySegmentation) that imports the shipped mode and overrides only the parts
    you need, exactly like longitudinal builds on basic.
  2. Customize an existing mode at runtime — change a shipped mode's toolbar,
    tools, or panels through per-mode customization keys, with no new package.

Building a derived mode

A derived mode imports the shipped mode's default export (which carries the
modeFactory) and its modeInstance, then spreads and overrides. Because the
default modeFactory applies immutability-helper
commands from modeConfiguration onto modeInstance, you can also override
via modeConfiguration rather than editing the instance directly.

js title="modes/my-segmentation/src/index.tsx"
import segmentationMode, { modeInstance as segModeInstance } from '@ohif/mode-segmentation';

const id = 'mySegmentation';

export const modeInstance = {
  ...segModeInstance,
  id,
  routeName: 'mySegmentation',
  displayName: 'My Segmentation',
  // Override only what you need. Toolbar buttons/sections and tool group
  // additions are plain composition arrays on the instance naming the
  // capability packs the mode uses (see below); panel lists are literal
  // arrays in the layout. Both are customized at runtime via the `mode` phase.
};

const mode = {
  ...segmentationMode, // carries modeFactory + extensionDependencies
  id,
  modeInstance,
};

export default mode;

The tmtv mode is extended the same way — import @ohif/mode-tmtv and its
modeInstance, then override.

Customizing a mode at runtime

The basic, longitudinal, segmentation, and tmtv modes declare their toolbar
buttons, toolbar sections, and tool-group additions as plain composition arrays on
the mode instance that name the capability packs the mode uses with { $reference }
markers (for example
toolbarButtons: [{ $reference: 'cornerstone.toolbarButtons' }, { $reference: 'cornerstone.segmentationToolbarButtons' }]).
The mode route seeds these onto the Mode customization scope on enter, alongside the
leftPanels / rightPanels panel lists. Because the values are lists whose
{ $reference } entries the customization service expands at read time, a window.config
entry or a ?customization= JSON module can add a whole capability pack (such as the
segmentation editing tools), remove a default, or swap the panels — targeting the mode
through a mode phase block (mode.basic, mode.segmentation, ...) without building
a new mode. See Compose whole capability blocks into a mode in the
Customization Service docs for the full key table, the reusable capability
blocks, and worked examples (adding segmentation editing to the basic and
longitudinal modes, and enabling annotation tools inside the segmentation mode).

Consuming Extensions

As mentioned in the Extensions section, in OHIF-v3
developers write their extensions to create reusable functionalities that later
can be used by modes. Now, it is time to describe how the registered
extensions will get utilized for a workflow mode via its id.

Each mode has a list of its extensions dependencies which are the
the extension name and version number. In addition, to use a module element you can use the
${extensionId}.${moduleType}.${element.name} schema. For instance, if a mode
requires the left panel with name of AIPanel that is added by the
myAIExtension via the following getPanelModule code, it should address it as
myAIExtension.panelModule.AIPanel inside the mode configuration file. In the
background OHIF will handle grabbing the correct panel via ExtensionManager.

js title="extensions/myaiextension/getpanelmodule.js"
import PanelAI from './PanelAI.js';

function getPanelModule({
  commandsManager,
  extensionManager,
  servicesManager,
}) {
  const wrappedAIPanel = () => {
    return (
      <PanelAI
        commandsManager={commandsManager}
        servicesManager={servicesManager}
      />
    );
  };

  return [
    {
      name: 'AIPanel',
      iconName: 'list-bullets',
      iconLabel: '',
      label: 'AI Panel',
      isDisabled: studies => {}, // optional
      component: wrappedAIPanel,
    },
  ];
}

Now, let's look at a simplified code of the basic viewer mode which consumes various functionalities
from different extensions.

js
const extensionDependencies = {
  '@ohif/extension-default': '^3.0.0',
  '@ohif/extension-cornerstone': '^3.0.0',
  '@ohif/extension-measurement-tracking': '^3.0.0',
};

const id = 'viewer';
const version = '3.0.0';

function modeFactory({ modeConfiguration }) {
  return {
    id,
    // ...
    routes: [
      {
        // ...
        layoutTemplate: ({ location, servicesManager }) => {
          return {
            id: ohif.layout,
            props: {
              leftPanels: ['@ohif/extension-measurement-tracking.panelModule.seriesList'],
              rightPanels: ['@ohif/extension-measurement-tracking.panelModule.trackedMeasurements'],
              viewports: [
                {
                  namespace: '@ohif/extension-measurement-tracking.viewportModule.cornerstone-tracked',
                  displaySetsToDisplay: ['@ohif/extension-default.sopClassHandlerModule.stack'],
                },
              ],
            },
          };
        },
      },
    ],
    extensions: extensionDependencies,
    hangingProtocol: ['@ohif/extension-default.hangingProtocolModule.petCT'],
    sopClassHandlers: ['@ohif/extension-default.sopClassHandlerModule.stack'],
    // ...
  };
}

const mode = {
  id,
  modeFactory,
  extensionDependencies,
}

export default mode

Routes

routes config is an array of route settings, and the overall look and behavior
of the viewer at the designated route is defined by the layoutTemplate and
init functions for the route. We will learn more about each of the above
properties inside the route documentation

HangingProtocols

Currently, you can pass your defined hanging protocols inside the
hangingProtocols property of the mode's config. If you specify the hanging protocol
explicitly by its name (only string and not array), it will be THE hanging protocol
that the mode runs with. However, if you specify an array of hanging protocols,
they will get ranked based on the displaySetSelector requirements and the winner
will be the hanging protocol that the mode runs with.

SopClassHandlers

Mode's configuration also accepts the sopClassHandler modules that have been
added by the extensions. This information will get used to initialize DisplaySetService with the provided SOPClass modules which
handles creation of the displaySets.

Hotkeys

hotkeys is another property in the configuration of a mode that can be defined
to add the specific hotkeys to the viewer on the mode route. Additionally, the
name under which the hotkeys are stored can be configured as hotkeyName.
This allows user customization of the mode specific hotkeys.

js
// default hotkeys
import { utils } from '@ohif/ui';

const { hotkeys } = utils;

const myHotkeys = [
  {
    commandName: 'setToolActive',
    commandOptions: { toolName: 'Zoom' },
    label: 'Zoom',
    keys: ['z'],
    isEditable: true,
  },
  {
    commandName: 'scaleUpViewport',
    label: 'Zoom In',
    keys: ['+'],
    isEditable: true,
  },
]

function modeFactory() {
  return {
    id: '',
    displayName: '',
    /*
    ...
    */
    hotkeys: {
      // The name in preferences to use for this set of hotkeys
      // Allows defining different sets for different modes
      name: 'custom-hotkey-name',
      // And the actual custom values here.
      hotkeys:[..hotkeys.defaults.hotkeyBindings, ...myHotkeys]
    },
  }
}

// exports

Registration

Similar to extension registration, viewer will look inside the pluginConfig.json to
find the modes to register.

js title=platform/app/pluginconfig.json
// Simplified version of the `pluginConfig.json` file
{
  "extensions": [
    {
      "packageName": "@ohif/extension-cornerstone",
      "version": "3.4.0"
    },
    // ...
  ],
  "modes": [
    {
      "packageName": "@ohif/mode-longitudinal",
      "version": "3.4.0"
    }
  ]
}

:::note
You can register modes by editing the pluginConfig.json file directly.
The provided cli can also add/remove/install/uninstall modes
(read more), but it is being phased out in
favour of generating modes with an agent.
:::

For the full set of entry fields and the three ways a plugin can be located
(in-tree, out-of-tree directory, or installed dependency), see the
pluginConfig.json reference.

The final registration and import of the modes happen inside a non-tracked file pluginImport.js (this file is also for internal use only).

:::note
You can stack multiple panel components on top of each other by providing an array of panel components in the rightPanels or leftPanels properties.

For instance we can use

text
rightPanels: [[dicomSeg.panel, tracked.measurements], [dicomSeg.panel, tracked.measurements]]

This will result in two panels, one with dicomSeg.panel and tracked.measurements and the other with dicomSeg.panel and tracked.measurements stacked on top of each other.

:::

APP Configuration of Modes

Modes based on the basic mode allow for customization using the immutability-helper
api within the app-config.js file as specified by the build process. For example,
to list the basic mode by default, and hide the longitudinal mode, the following
configuration from config/kheops.js can be used:

text
... app config file
  modesConfiguration: {
    '@ohif/mode-basic': {
      hide: { $set: false },
      displayName: { $set: 'Basic' },
    },
    '@ohif/mode-longitudinal': {
      hide: { $set: true },
    },
  },

Default Modes

There are a number of modes provided in a default OHIF installation. These
are described here, along with some amount of information about extending/configuration
of those modes.

Modes which are loaded by default, but which are hidden can be activated by
using a direct URL launch. For example, to show a study in the basic mode,
use the URL for the longitudinal mode, and replace the /viewer with /basic

Basic (NOT `Basic Viewer`, which got assigned to `longitudinal`)

The basic mode is a mode that demonstrates the base capabilities of the OHIF
system, without including features such as longitudinal tracking, segmentation editing
or other custom capabilities. The left hand panel uses the study browser thumbnails
without tracking, and the right hand panel uses the basic segmentation panel and the
measurements without tracking (longitudinal) layouts. This makes it a good overall
base for using when the tracking behaviour of longitudinal mode is not desired.

It can be used in a default install by direct URL launch to the /basic endpoint
instead of the /viewer endpoint.

Longitudinal (The `Basic Viewer` label in OHIF)

The longitudinal mode adds the tracking for measurements in the study browser
and in the measurements panel, and is otherwise identical to the basic mode.


Platform Docs Docs Platform Services Index (`platform/docs/docs/platform/services/index.md`)


Services

Overview

Services are "concern-specific" code modules that can be consumed across layers.
Services provide a set of operations, often tied to some shared state, and are
made available to through out the app via the ServicesManager. Services are
particularly well suited to address cross-cutting
concerns
.

Each service should be:

  • self-contained
  • able to fail and/or be removed without breaking the application
  • completely interchangeable with another module implementing the same interface

In OHIF-v3 we have added multiple non-UI services and have introduced
pub/sub pattern to reduce coupling between layers.

Read more about Pub/Sub

Services

The following services is available in the OHIF-v3.

Service Type Description
DicomMetadataStore Data Service DicomMetadataStore
DisplaySetService Data Service DisplaySetService
segmentationService Segmentation Service segmentationService
HangingProtocolService Data Service HangingProtocolService
MeasurementService (MODIFIED) Data Service MeasurementService
ToolBarService Data Service ToolBarService
ViewedDataService Data Service viewedDataService
ViewportGridService UI Service ViewportGridService
Cine Service UI Service cine
CustomizationService UI Service customizationService
UIDialogService UI Service UIDialogService
UIModalService UI Service UIModalService
UINotificationService UI Service UINotificationService
UIViewportDialogService UI Service UIViewportDialogService

Platform Docs Docs User Guide Viewer Index (`platform/docs/docs/user-guide/viewer/index.md`)


Overview

When you open a mode, viewport, toolbar and panels of the mode get shown.
It is important to note that each mode has a different UI, which serves its purpose.
Here we explain various components of Basic Viewer mode which includes measurement
tracking functionalities.

Basic viewer mode (longitudinal):

Let's break different aspects of the viewer to the main components:

  • Left Panel (study panel): displays series thumbnails with series details
  • Viewport: renders the image and displays annotations
  • Right Panel (measurements): displays annotations details
  • Toolbar: displays tools and logo

Now, we explain each component and its sub-elements in detail.


Platform Docs Versioned Docs Version 3.11 Deployment Index (`platform/docs/versioned_docs/version-3.11/deployment/index.md`)


Deployment

The OHIF Viewer can be served as a stand-alone PWA (progressive web
application
) by building and hosting a collection of static assets or be embedded in other web applications via an iframe if needed. In
either case, you will need to configure your instance of the Viewer so that it
can connect to your data source (the database or PACS that provides the data
your Viewer will display).

:::tip
Our goal is to make deployment as simple and painless as possible; however,
there is an inherent amount of complexity in configuring and deploying web
applications. If you find yourself a little lost, please don't hesitate to
reach out to for help.
:::

Deployment Scenarios

Stand-alone Viewer

Deploying the OHIF Viewer as a stand-alone web application provides many
benefits, but comes at the cost of time and complexity. Some benefits include:

Today:

  • Leverage extensions and
    modes to drop-in powerful new features
  • Add routes and customize the viewer's workflow
  • Finer control over styling and whitelabeling

In the future:

Hosted Static Assets

At the end of the day, a production OHIF Viewer instance is a collection of
HTML, CSS, JS, Font Files, and Images. We "build" those files from our
source code with configuration specific to our project. We then make those
files publicly accessible by hosting them on a Web Server.

Part 1 - Build Production Assets

"Building", or creating, the files you will need is the same regardless of the
web host you choose. You can find detailed instructions on how to configure and
build the OHIF Viewer in our
"Build for Production" guide.

Part 2 - Host Your App

There are a lot of benefits to hosting static assets over
dynamic content. You can find instructions on how to host your build's output
via one of these guides:

Drag-n-drop

Easy

Advanced

Embedded Viewer (iframe)

OHIF-v3 has deprecated deploying the viewer as an embedded viewer via a script
tag as the number of underlying libraries that run web workers are increasing for OHIF. An example of these libraries is OHIF's 3D rendering functionality that is provided by
vtk-js.

However, you can still embed the viewer using an iframe. You can utilize the iframe element to load the OHIF viewer and establish communication with it using the postMessage API if needed.
Read more about how to use the iframe here.

Data

The OHIF Viewer is able to connect to any data source that implements the DICOM
Web Standard
. DICOM Web refers to RESTful
DICOM Services -- a recently standardized set of guidelines for exchanging
medical images and imaging metadata over the internet. Not all archives fully
support it yet, but it is gaining wider adoption.

Configure Connection

If you have an existing archive and intend to host the OHIF Viewer at the same
domain name as your archive, then connecting the two is as simple as following
the steps laid out in our
Configuration Essentials Guide.

What if I don't have an imaging archive?

We provide some guidance on configuring a local image archive in our
Data Source Essentials
guide. Hosting an archive remotely is a little trickier. You can check out some
of our advanced recipes for modeled setups that may work for you.

What if I intend to host the OHIF Viewer at a different domain?

There are two important steps to making sure this setup works:

  1. Your Image Archive needs to be exposed, in some way, to the open web. This
    can be directly, or through a reverse proxy, but the Viewer needs some
    way
    to request its data.
  2. * Your Image Archive needs to have appropriate CORS (Cross-Origin Resource
    Sharing) Headers

* Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional
HTTP headers to tell a browser to let a web application running at one origin
(domain) have permission to access selected resources from a server at a
different origin. - MDN Web Docs: Web - Http - CORS

Most image archives do not provide either of these features "out of the box".
It's common to use IIS, Nginx, or Apache to route incoming requests and append
appropriate headers. You can find an example of this setup in our
Nginx + Image Archive Deployment Recipe.

What if my archive doesn't support DicomWeb?

It's possible to supply all Study data via JSON format, in the event you do not
have a DicomWeb endpoint. You can host all of the relevant files on any web
accessible server (Amazon S3, Azure Blob Storage, Local file server etc.)

This JSON is supplied via the '?url=' query parameter. It should reference an
endpoint that returns application/json formatted text.

If you do not have an API, you can simply return a text file containing the JSON
from any web server.

You tell the OHIF viewer to use JSON by using the dicomjson datasource and
appending '?url=' query to your mode's route:

e.g.
https://my-test-ohif-server/myMode/dicomjson?url=https://my-json-server/study-uid.json

The returned JSON object must contain a single root object with a 'studies'
array.

You can read more about using different data sources for mode's routes
here

Sample JSON format:

text
/* Detailed source-code truncated for AI context efficiency. */

More info on this JSON format can be found here
Issue #1500

Implementation Notes:

  1. For each instance url (dicom object) in the returned JSON, you must prefix
    the url with dicomjson: in order for the cornerstone image loader to
    retrieve it correctly. eg. https://image-server/my-image.dcm --->
    dicomjson:https://image-server/my-image.dcm
  2. The JSON format above is compatible with >= v3.7.8 of the application in V2
    version. Older versions of the viewer used a different JSON format. As of
    20/04/20 the public [https://viewer.ohif.org/] is a pre 3.0 version that does
    not support this format yet.
  3. The JSON format is case-sensitive. Please ensure you have matched casing with
    the naturalised Dicom format referenced in
    Issue #1500.

CORS Issues (Cross-Origin Resource Sharing)

If you host a JSON API or Images on a different domain from the app itself,
you will likely have CORS issues. This will also happen when testing from
Localhost and reaching out to remote servers. Even if the domain is the same,
different ports, subdomains or protocols (https vs http) will also cause CORS
errors. You will to need add a configuration on each server hosting these assets
to allow your App server origin.

For example:

Let's assume your application is hosted on https://my-ohif-server.com.

Your JSON API is hosted on https://my-json-api.aws.com

And your images are stored on Amazon S3 at https://my-s3-bucket.aws.com

When you first start your application, browsing to
https://my-ohif-server.com/myMode/dicomjson?url=https://my-json-api.aws.com/api/my-json-study-info.json,
you will likely get a CORS error in the browser console as it tries to connect
to https://my-json-api.aws.com.

Adding a setting on the JSON server to allow the CORS origin =
https://my-ohif-server.com should solve this.

Next, you will likely get a similar CORS error, as the browser tries to go to
https://my-s3-bucket.aws.com. You will need to go to the S3 bucket
configuration, and add a CORS setting to allow origin =
https://my-ohif-server.com.

Essentially, whenever the application connects to a remote resource, you will
need to add the applications url to the allowed CORS Origins on that resource.
Adding an origin similar to https://localhost:3000 will also allow for local
testing.

Securing Your Data

Coming soon

Recipes

We've included a few recipes for common deployment scenarios. There are many,
many possible configurations, so please don't feel limited to these setups.
Please feel free to suggest or contribute your own recipes.


Platform Docs Versioned Docs Version 3.11 Development Getting Started (`platform/docs/versioned_docs/version-3.11/development/getting-started.md`)


Getting Started

Setup

Fork & Clone

If you intend to contribute back changes, or if you would like to pull updates
we make to the OHIF Viewer, then follow these steps:

  • Fork the OHIF/Viewers repository
  • Create a local clone of your fork
    • git clone https://github.com/YOUR-USERNAME/Viewers
  • Add OHIF/Viewers as a remote repository labeled upstream
    • Navigate to the cloned project's directory
    • git remote add upstream https://github.com/OHIF/Viewers.git

With this setup, you can now sync your fork to keep it
up-to-date with the upstream (original) repository. This is called a "Triangular
Workflow" and is common for Open Source projects. The GitHub blog has a good
graphic that illustrates this setup
.

Private

Alternatively, if you intend to use the OHIF Viewer as a starting point, and you
aren't as concerned with syncing updates, then follow these steps:

  1. Navigate to the OHIF/Viewers repository
  2. Click Clone or download, and then Download ZIP
  3. Use the contents of the .zip file as a starting point for your viewer

NOTE: It is still possible to sync changes using this approach. However,
submitting pull requests for fixes and features are best done with the
separate, forked repository setup described in "Fork & Clone"

Developing

Branches

`master` branch - The latest dev (beta) release

  • master - The latest dev release

This is typically where the latest development happens. Code that is in the master branch has passed code reviews and automated tests, but it may not be deemed ready for production. This branch usually contains the most recent changes and features being worked on by the development team. It's often the starting point for creating feature branches (where new features are developed) and hotfix branches (for urgent fixes).

Each package is tagged with beta version numbers, and published to npm such as @ohif/[email protected]

`release/*` branches - The latest stable releases

Once the master branch code reaches a stable, release-ready state, we conduct a comprehensive code review and QA testing. Upon approval, we create a new release branch from master. These branches represent the latest stable version considered ready for production.

For example, release/3.5 is the branch for version 3.5.0, and release/3.6 is for version 3.6.0. After each release, we wait a few days to ensure no critical bugs. If any are found, we fix them in the release branch and create a new release with a minor version bump, e.g., 3.5.1 in the release/3.5 branch.

Each package is tagged with version numbers and published to npm, such as @ohif/[email protected]. Note that master is always ahead of the release branch. We publish docker builds for both beta and stable releases.

Here is a schematic representation of our development workflow:

Requirements

  • Node.js & NPM
  • Yarn
  • Yarn workspaces should be enabled:
    • yarn config set workspaces-experimental true

Kick the tires

Navigate to the root of the project's directory in your terminal and run the
following commands:

bash
# Restore dependencies
yarn install

# Start local development server
yarn run dev

You should see the following output:

bash
@ohif/app: i 「wds」: Project is running at http://localhost:3000/
@ohif/app: i 「wds」: webpack output is served from /
@ohif/app: i 「wds」: Content not from webpack is served from D:\code\ohif\Viewers\platform\viewer
@ohif/app: i 「wds」: 404s will fallback to /index.html

# And a list of all generated files

🎉 Celebrate 🎉

Building for Production

More comprehensive guides for building and publishing can be found in our
deployment docs

bash
# Build static assets to host a PWA
yarn run build

Troubleshooting

  • If you receive a "No Studies Found" message and do not see your studies, try
    changing the Study Date filters to a wider range.
  • If you see a 'Loading' message which never resolves, check your browser's
    JavaScript console inside the Developer Tools to identify any errors.

Platform Docs Versioned Docs Version 3.11 Faq Index (`platform/docs/versioned_docs/version-3.11/faq/index.md`)


id: index title: OHIF Viewer FAQ summary: Comprehensive list of frequently asked questions about the OHIF Viewer, covering common inquiries about reporting bugs, requesting features, academic collaborations, regulatory status, and obtaining demo studies.

General FAQ

How do I report a bug?

Navigate to our GitHub Repository, and submit a new bug report.
Follow the steps outlined in the Bug Report Template.

How can I request a new feature?

At the moment we are in the process of defining our roadmap and will do our best
to communicate this to the community. If your requested feature is on the
roadmap, then it will most likely be built at some point. If it is not, you are
welcome to build it yourself and contribute it.
If you have resources and would like to fund the development of a feature,
please contact us.

Who should I contact about Academic Collaborations?

Gordon J. Harris
at Massachusetts General Hospital is the primary contact for any academic
collaborators. We are always happy to hear about new groups interested in using
the OHIF framework, and may be able to provide development support if the
proposed collaboration has an impact on cancer research.

Does OHIF offer support?

yes, you can contact us for more information here

Does The OHIF Viewer have [510(k) Clearance][501k-clearance] from the U.S. F.D.A or [CE Marking][ce-marking] from the European Commission?

NO. The OHIF Viewer is NOT F.D.A. cleared or CE Marked. It is the users'
responsibility to ensure compliance with applicable rules and regulations. The
License for the OHIF
Platform does not prevent your company or group from seeking F.D.A. clearance
for a product built using the platform.

If you have gone this route (or are going there), please let us know because we
would be interested to hear about your experience.

Is there a DICOM Conformance Statement for the OHIF Viewer?

Yes, check it here DICOM Conformance Statement

Is The OHIF Viewer [HIPAA][hipaa-def] Compliant?

NO. The OHIF Viewer DOES NOT fulfill all of the criteria to become HIPAA
Compliant. It is the users' responsibility to ensure compliance with applicable
rules and regulations.

Could you provide me with a particular study from the OHIF Viewer Demo?

You can check out the studies that we have put in this Dropbox link


Platform Docs Versioned Docs Version 3.11 Migration Guide Index (`platform/docs/versioned_docs/version-3.11/migration-guide/index.md`)


import DocCardList from '@theme/DocCardList';

Migration Guides

Based on the version you are migrating from, you can find the migration guide for the latest version of the platform.


Platform Docs Versioned Docs Version 3.11 User Guide Index (`platform/docs/versioned_docs/version-3.11/user-guide/index.md`)


Study List

Overview

The first page you will see when the viewer is loaded is the Study List. In
this page you can explore all the studies that are stored on the configured
server for the OHIF Viewer.

Sorting

When the Study List is opened, the application queries the PACS for 101 studies
by default. If there are greater than 100 studies returned, the default sort for
the study list is dictated by the image archive that hosts these studies for the
viewer and study list sorting will be disabled. If there are less than or equal
to 100 studies returned, they will be sorted by study date (most recent to
oldest) and study list sorting will be enabled. Whenever a query returns greater
than 100 studies, use filters to narrow results below 100 studies to enable
Study List sorting.

Filters

There are certain filters that can be used to limit the study list to the
desired criteria.

  • Patient Name: Searches between patients names
  • MRN: Searches between patients Medical Record Number
  • Study Date: Filters the date of the acquisition
  • Description: Searches between study descriptions
  • Modality: Filters the modalities
  • Accession: Searches between patients accession number

An example of using study list filter is shown below:

Below the study list are pagination options for 25, 50, or 100 studies per page.

For static wado servers, you can enable fuzzy matching by setting the supportsFuzzyMatching property to true, after enabling it, fuzzy matching will be peformed on the patient name field, for example, if PatientName is "John^Doe", then "jo", "Do" and "John Doe" will all match. However "ohn" will not match.

Study Summary

Click on a study to expand the study summary panel.

A summary of series available in the study is shown, which contains the series
description, series number, modality of the series, instances in the series, and
buttons to launch viewer modes to display the study.

Study Specific Modes

All available modes are seen in the study expanded view. Modes can be enabled or
disabled for a study based on the modalities contained within the study.

In the screenshot below, there are two modes shown for the selected study

  • Basic Viewer: Default mode that enables rendering and measurement tracking

  • PET/CT Fusion: Mode for visualizing the PET CT study in a 3x3 format.

Based on the mode configurations (e.g., available modalities), PET/CT mode is
disabled for studies that do not contain PET AND CT images.

The previous screenshot shows a study containing PET and CT images and both
Basic Viewer and PET/CT Mode are available.

View Study

The Basic Viewer mode is available for all studies by default. Click on the
mode button to launch the viewer.


Platform Docs Docs Migration Guide 3p8 To 3p9 1 Segmentation Index (`platform/docs/docs/migration-guide/3p8-to-3p9/1-segmentation/index.md`)


id: segmentation-index title: Segmentation sidebar_position: 1 summary: Migration guide for segmentation architecture changes in OHIF 3.9, covering the shift from tool group-centric to viewport-centric architecture to support advanced visualization capabilities and more flexible segmentation handling.

import DocCardList from '@theme/DocCardList';

:::info
This migration involves significant architectural changes to the segmentation system. While we typically aim for incremental updates, the shift from a tool group-centric to a viewport-centric architecture was necessary to support OHIF 3.9's advanced visualization capabilities, and more flexible segmentation handling.

Don't worry - we'll guide you through each change step by step!
:::


Platform Docs Docs Migration Guide 3p9 To 3p10 2 CustomizationService Index (`platform/docs/docs/migration-guide/3p9-to-3p10/2-CustomizationService/index.md`)


CustomizationService

Key Changes:

  1. Unified Customization Getter:

    • The getCustomization method now uniformly retrieves customizations, prioritizing global, then mode, and finally default customizations.
    • The defaultValue parameter in getCustomization is no longer used for setting defaults. It simply returns if no customization is found.
    • The methods getModeCustomization and getGlobalCustomization are deprecated.
  2. Simplified Customization Registration:

    • The customizationType property in customization definitions is renamed to inheritsFrom.

    • The merge property in customization definitions is removed. Instead, a customization is merged using the helper methods. The basic update commands are listed in the table below, and you can learn more about the helper methods here.

      Command Description Example
      $set Replace a value entirely Replace a list or object
      $push Append items to an array Add to the end of a list
      $unshift Prepend items to an array Add to the start of a list
      $splice Insert, remove, or replace at specific index Modify specific indices in a list
      $merge Update specific fields in an object Change a subset of fields
      $apply Compute the new value dynamically Apply a function to transform values
      $filter Find and update specific items in arrays Target nested structures based on matching criteria
  3. New $transform command:

    • If you were using the transform command, you should now use the $transform command. Just a simple rename to make it more consistent with the other commands.
  4. Renamed CornerstoneOverlay customizations:

    • The cornerstoneOverlay customizations (cornerstoneOverlayTopLeft, cornerstoneOverlayTopRight, cornerstoneOverlayBottomLeft, cornerstoneOverlayBottomRight) have been renamed to viewportOverlay.topLeft, viewportOverlay.topRight, viewportOverlay.bottomLeft, and viewportOverlay.bottomRight. See dedicated page for customizing viewport overlays here.
  5. Renamed customRoutes:

    • The customRoutes customization is renamed to routes.customRoutes.
  6. contextMenu customization:

    • The contextMenu customization now uses the inheritsFrom property to inherit from other context menus, previously it was called customizationType
  7. New immutability-helper dependency:
    The immutability-helper library is now used for merging customizations. If you encounter an error related to it, you'll need to install it - though OHIF should really handle the installation for you, so this is pretty much just a heads up.

Migration Steps:

  1. Replace getModeCustomization and getGlobalCustomization with getCustomization:

    • Before:

      javascript
      const tools = customizationService.getModeCustomization(
        'cornerstone.overlayViewportTools'
      )?.tools;
      const globalValue = customizationService.getGlobalCustomization('someGlobalKey');
    • After:

      javascript
      const tools = customizationService.getCustomization('cornerstone.overlayViewportTools');
      const globalValue = customizationService.getCustomization('someGlobalKey');

      :::note
      The returned value is the actual customization value, not an object that needs to be broken down.
      :::

  2. Update Customization Definitions:

    • We've moved away from using random items in the customization definition, and now we use the id property to identify the customization as a value. Previously, it was referred to as value, values, and so on, but now an id is used to reference the customization. This approach really simplifies things - when you need to grab the customization, you can just use the id to get it, and you don't have to bother with destructuring the value from the object.

Example: Customizing a Panel

Before (v3.9):

javascript
// the default value was hardcoded inside the panel itself - bad idea!
// default was given in the panel itself

// PanelSegmentation.tsx

// Retrieve the onSegmentationAdd customization
const { onSegmentationAdd } = customizationService.getCustomization(
  'PanelSegmentation.onSegmentationAdd',
  {
    id: 'segmentation.onSegmentationAdd',
    onSegmentationAdd: handlers.onSegmentationAdd,
  }
);

// Retrieve the disableEditing customization
const { disableEditing } = customizationService.getCustomization(
  'PanelSegmentation.disableEditing',
  {
    id: 'default.disableEditing',
    disableEditing: false,
  }
);



// mode was customizing it via
customizationService.addModeCustomizations([
  {
    id: 'PanelSegmentation.tableMode',
    mode: 'expanded',
  },
  {
    id: 'PanelSegmentation.showAddSegment',
    showAddSegment: false,
  },
]);

After (v3.10):

javascript
// cornerstone extension getCustomizationModule
// centralized customization location for all extensions - good!
function getCustomizationModule() {
  return [
    {
      name: 'default',
      value: {
        'panelSegmentation.disableEditing': false,
        'panelSegmentation.showAddSegment': true,
      },
    },
  ];
}


// inside panelSegmentation.tsx
const disableEditing = customizationService.getCustomization('panelSegmentation.disableEditing');
const showAddSegment = customizationService.getCustomization('panelSegmentation.showAddSegment');


// mode can customize it via $ operators for mode customizations
customizationService.setCustomizations({
  'panelSegmentation.disableEditing': { $set: true },
  'panelSegmentation.showAddSegment': { $set: false },
});


//or via configuration for global customizations
window.config = {
  // rest of config
  customizationService: [
    {
      'panelSegmentation.disableEditing': {
        $set: true, // Disables editing of segmentations in the panel
      },
    },
  ],
  // rest of config
};

Example: Updating a Customization

Let's say you have a customization in v3.9 that adds a custom overlay item to the top-left corner:

Before (v3.9):

javascript
// In your mode's onModeEnter
customizationService.addModeCustomizations([
  {
    id: 'cornerstoneOverlayTopLeft',
    items: [
      {
        id: 'myCustomOverlay',
        customizationType: 'ohif.overlayItem',
        attribute: 'PatientName',
        label: 'Patient:',
      },
    ],
  },
]);

After (v3.10):

javascript
// In your mode's onModeEnter or elsewhere
customizationService.setCustomizations({
  'viewportOverlay.topLeft': {
    $push: [
      {
        id: 'myCustomOverlay',
        inheritsFrom: 'ohif.overlayItem',
        attribute: 'PatientName',
        label: 'Patient:',
      },
    ],
  },
});
text
**Example: Customizing viewport action Menu**

**Before (v3.9):**

```javascript
// In your configuration for global customizations
window.config = {
    // rest of config
    addWindowLevelActionMenu: true,
};

After (v3.10):

javascript
// you can now handle each action menu item (windowLevelActionMenu and segmentationOverlay) separately

// cornerstone extension getCustomizationModule
function getCustomizationModule() {
    return [
        {
            name: 'default',
            value: {
                'viewportActionMenu.windowLevelActionMenu': {
                    enabled: true,
                    location: viewportActionCornersService.LOCATIONS.topRight,
                },
                'viewportActionMenu.segmentationOverlay': {
                    enabled: true,
                    location: viewportActionCornersService.LOCATIONS.topRight,
                },
            },
        },
    ];
}


// Accessing customizations within your component (e.g., OHIFCornerstoneViewport.tsx)
const windowLevelActionMenu = customizationService.getCustomization('viewportActionMenu.windowLevelActionMenu');
const segmentationOverlay = customizationService.getCustomization('viewportActionMenu.segmentationOverlay');

// Modifying customizations at runtime, for example, in your mode's onModeEnter
customizationService.setCustomizations({
    'viewportActionMenu.windowLevelActionMenu': {
        $set: {
            enabled: false,
            location: viewportActionCornersService.LOCATIONS.bottomLeft,
        },
    },
    'viewportActionMenu.segmentationOverlay': {
        $set: {
            enabled: true,
            location: viewportActionCornersService.LOCATIONS.topLeft,
        },
    },
});

// Alternatively, setting global customizations via configuration
window.config = {
    // rest of config
    customizationService: [
        {
            'viewportActionMenu.windowLevelActionMenu': {
                $set: {
                    enabled: false,
                    location: 1,
                },
            },
            'viewportActionMenu.segmentationOverlay': {
                $set: {
                    enabled: true,
                    location: 1,
                },
            },
        },
    ],
    // rest of config
};

Note:

  • The customizationType is replaced with inheritsFrom.

Renaming

To keep our customization system consistent, you should be aware of a few key renaming conventions. We now follow a straightforward naming convention for customizations: scopeName.customizationItem.

Customization Key (Old) Customization Key (New) Description
PanelMeasurement.disableEditing panelMeasurement.disableEditing Disables editing measurements in the Measurement Panel and after SR hydration.
PanelSegmentation.CustomDropdownMenuContent panelSegmentation.customDropdownMenuContent Custom content for the dropdown menu in the Segmentation Panel.
PanelSegmentation.disableEditing panelSegmentation.disableEditing Disables editing segmentations in the Segmentation Panel.
PanelSegmentation.showAddSegment panelSegmentation.showAddSegment Controls visibility of the "Add Segment" button in the Segmentation Panel.
PanelSegmentation.onSegmentationAdd panelSegmentation.onSegmentationAdd Custom function to execute when a new segmentation is added.
PanelSegmentation.tableMode panelSegmentation.tableMode Controls the table mode (collapsed/expanded) in the Segmentation Panel.
PanelSegmentation.readableText panelSegmentation.readableText Custom readable text labels for the Segmentation Panel.
PanelStudyBrowser.studyMode studyBrowser.studyMode Controls the study mode (all/primary/recent) in the Study Browser Panel.
customRoutes routes.customRoutes Defines custom routes for the application.
cornerstoneOverlayTopLeft viewportOverlay.topLeft Custom overlay items for the top-left corner of the viewport.
cornerstoneOverlayTopRight viewportOverlay.topRight Custom overlay items for the top-right corner of the viewport.
cornerstoneOverlayBottomLeft viewportOverlay.bottomLeft Custom overlay items for the bottom-left corner of the viewport.
cornerstoneOverlayBottomRight viewportOverlay.bottomRight Custom overlay items for the bottom-right corner of the viewport.
(New) viewportActionMenu.windowLevelActionMenu Controls the display and the location of the window level action menu in the viewport.
(New) viewportActionMenu.segmentationOverlay Controls the display and the location of segmentation overlays in the viewport.

Platform Docs Docs Platform Services Data Index (`platform/docs/docs/platform/services/data/index.md`)


Overview

Data services are the first category of services which deal with handling non-ui
related state Each service have their own internal state which they handle.

We have replaced the redux store. Instead, we have introduced various
services and a pub/sub pattern to subscribe and run, which makes the OHIF-v3
architecture nice and clean.

We maintain the following non-ui Services:

Service Architecture

We have explained services and how to create a custom service in the
ServicesManager section of the docs

To recap: The simplest service return a new object that has a name property,
and Create method which instantiate the service class. The "Factory Function"
that creates the service is provided with the implementation (this is slightly
different for UI Services).

js
// extensions/customExtension/src/services/backEndService/index.js
import backEndService from './backEndService';

export default function WrappedBackEndService(servicesManager) {
  return {
    name: 'myService',
    create: ({ configuration = {} }) => {
      return new backEndService(servicesManager);
    },
  };
}

A service, once created, can be registered with the ServicesManager to make it
accessible to extensions. Similarly, the application code can access named
services from the ServicesManager.

Read more of how to design a new custom service and register it


Platform Docs Docs Platform Services Ui Index (`platform/docs/docs/platform/services/ui/index.md`)


Overview

A typical web application will have components and state for common UI like
modals, notifications, dialogs, etc. A UI service makes it possible to leverage
these components from an extension.

We maintain the following UI Services:

Providers for UI services

There are several context providers that wraps the application routes. This
makes the context values exposed in the app, and service's setImplementation
can get run to override the implementation of the service.

js title="platform/app/src/app.jsx"
function App({ config, defaultExtensions }) {
  /**...**/
  /**...**/
  return (
    /**...**/
    <ViewportGridProvider service={ViewportGridService}>
      <ViewportDialogProvider service={UIViewportDialogService}>
        <CineProvider service={CineService}>
          <SnackbarProvider service={UINotificationService}>
            <DialogProvider service={UIDialogService}>
              <ModalProvider modal={Modal} service={UIModalService}>
                {appRoutes}
              </ModalProvider>
            </DialogProvider>
          </SnackbarProvider>
        </CineProvider>
      </ViewportDialogProvider>
    </ViewportGridProvider>
    /**...**/
  );
}

Example

For instance UIModalService has the following Public API:

js title="platform/core/src/services/uimodalservice/index.js"
const publicAPI = {
  name,
  hide: _hide,
  show: _show,
  setServiceImplementation,
};

function setServiceImplementation({
  hide: hideImplementation,
  show: showImplementation,
}) {
  /** ... **/
  serviceImplementation._hide = hideImplementation;
  serviceImplementation._show = showImplementation;
  /** ... **/
}

export default {
  name: 'UIModalService',
  create: ({ configuration = {} }) => {
    return publicAPI;
  },
};

UIModalService implementation can be set (override) in its context provider.
For instance in ModalProvider we have:

text
/* Detailed source-code truncated for AI context efficiency. */

Therefore, anywhere in the app that we have access to react context we can use
it by calling the useModal from @ohif/ui-next. As a matter of fact, we are
utilizing the modal for the preference window which shows the hotkeys after
clicking on the gear button on the right side of the header.

A simplified code for our viewer header is:

tsx title="extensions/default/src/viewerlayout/viewerheader.tsx"
import { Header, useModal } from '@ohif/ui-next';
import { useSystem } from '@ohif/core';

function ViewerHeader({ appConfig }) {
  const { servicesManager } = useSystem();
  const { customizationService } = servicesManager.services;
  const { show } = useModal();

  const AboutModal = customizationService.getCustomization('ohif.aboutModal');
  const UserPreferencesModal = customizationService.getCustomization(
    'ohif.userPreferencesModal'
  );

  const menuOptions = [
    {
      title: AboutModal?.menuTitle ?? t('Header:About'),
      icon: 'info',
      onClick: () =>
        show({
          content: AboutModal,
          title: AboutModal?.title ?? t('AboutModal:About OHIF Viewer'),
          containerClassName: AboutModal?.containerClassName ?? 'max-w-md',
        }),
    },
    {
      title: UserPreferencesModal.menuTitle ?? t('Header:Preferences'),
      icon: 'settings',
      onClick: () =>
        show({
          content: UserPreferencesModal,
          title: UserPreferencesModal.title ?? t('UserPreferencesModal:User preferences'),
          containerClassName:
            UserPreferencesModal?.containerClassName ?? 'flex max-w-4xl p-6 flex-col',
        }),
    },
  ];

  /** ... **/

  return <Header menuOptions={menuOptions} /** ... **/ />;
}

Tips & Tricks

It's important to remember that all we're doing is making it possible to control
bits of the application's UI from an extension. Here are a few non-obvious
takeaways worth mentioning:

  • Your application code should continue to use React context
    (consumers/providers) as it normally would
  • You can substitute our "out of the box" UI implementations with your own
  • You can create and register your own UI services
  • You can choose not to register a service or provide a service implementation
  • In extensions, you can provide fallback/alternative behavior if an expected
    service is not registered
    • No UIModalService? Use the UINotificationService to notify users.
  • You can technically register a service in an extension and expose it to the
    core application

Note: These are recommended patterns, not hard and fast rules. Following them
will help reduce confusion and interoperability with the larger OHIF
community, but they're not silver bullets. Please speak up, create an issue,
if you would like to discuss new services or improvements to this pattern.


Platform Docs Versioned Docs Version 3.11 Migration Guide 3p10 To 3p11 Index (`platform/docs/versioned_docs/version-3.11/migration-guide/3p10-to-3p11/index.md`)


Migration Guide

This guide provides information about migrating from OHIF version 3.10 to version 3.11.


Platform Docs Versioned Docs Version 3.11 Migration Guide 3p11 To 3p12 Index (`platform/docs/versioned_docs/version-3.11/migration-guide/3p11-to-3p12/index.md`)


Migration Guide

This guide provides information about migrating from OHIF version 3.11 to version 3.12 beta


Platform Docs Versioned Docs Version 3.11 Migration Guide 3p8 To 3p9 Index (`platform/docs/versioned_docs/version-3.11/migration-guide/3p8-to-3p9/index.md`)


id: 3p8-to-3p9 title: 3.8 -> 3.9 sidebar_position: 2 summary: Migration guide for upgrading from OHIF 3.8 to 3.9, covering segmentation architecture changes, renamings, data sources, measurements, viewport action corners, state sync service, RT structure improvements, UI changes, and other refactorings.

import DocCardList from '@theme/DocCardList';

Migration Guide Sections


Platform Docs Versioned Docs Version 3.11 Migration Guide 3p9 To 3p10 Index (`platform/docs/versioned_docs/version-3.11/migration-guide/3p9-to-3p10/index.md`)


Migration Guide

General


Platform Docs Versioned Docs Version 3.11 Platform Extensions Index (`platform/docs/versioned_docs/version-3.11/platform/extensions/index.md`)


Introduction

We have re-designed the architecture of the OHIF-v3 to enable building
applications that are easily extensible to various use cases (modes) that behind
the scene would utilize desired functionalities (extensions) to reach the goal
of the use case.

Previously, extensions were “additive” and could not easily be mixed and matched
within the same viewer for different use cases. Previous OHIF-v2 architecture
meant that any minor extension alteration usually would require the user to hard
fork. E.g. removing some tools from the toolbar of the cornerstone
extension meant you had to hard fork it, which was frustrating if the
implementation was otherwise the same as master.

  • Developers should make packages of reusable functionality as extensions,
    and can consume publicly available extensions.
  • Any conceivable radiological workflow or viewer setup will be able to be
    built with the platform through modes.

Practical examples of extensions include:

Diagram showing how extensions are configured and accessed.

Extension Skeleton

An extension is a plain JavaScript object that has id and version properties, and one or
more modules and/or lifecycle hooks.

js
// prettier-ignore
export default {
  /**
   * Required properties. Should be a unique value across all extensions.
   */
  id,

  // Lifecycle
  preRegistration() { /* */ },
  onModeEnter() { /* */ },
  onModeExit() { /* */ },
  // Modules
  getLayoutTemplateModule() { /* */ },
  getDataSourcesModule() { /* */ },
  getSopClassHandlerModule() { /* */ },
  getPanelModule() { /* */ },
  getViewportModule() { /* */ },
  getCommandsModule() { /* */ },
  getContextModule() { /* */ },
  getToolbarModule() { /* */ },
  getHangingProtocolModule() { /* */ },
  getUtilityModule() { /* */ },
}

OHIF-Maintained Extensions

A small number of powerful extensions for popular use cases are maintained by
OHIF. They're co-located in the OHIF/Viewers repository, in
the top level extensions/ directory.

Extension Description Modules
default Default extension provides default viewer layout, a study/series browser, and a datasource that maps to a DICOMWeb compliant backend commandsModule, ContextModule, DataSourceModule, HangingProtocolModule, LayoutTemplateModule, PanelModule, SOPClassHandlerModule, ToolbarModule
cornerstone Provides 2d and 3d rendering functionalities ViewportModule, CommandsModule, UtilityModule
dicom-pdf Renders PDFs for a specific SopClassUID. Viewport, SopClassHandler
dicom-video Renders DICOM Video files. Viewport, SopClassHandler
cornerstone-dicom-sr Maintained extensions for cornerstone and visualization of DICOM Structured Reports ViewportModule, CommandsModule, SOPClassHandlerModule
measurement-tracking Tracking measurements in the measurement panel ContextModule,PanelModule,ViewportModule,CommandsModule

Registering of Extensions

viewer starts by registering all the extensions specified inside the
pluginConfig.json, by default we register all extensions in the repo.

js title=platform/app/pluginconfig.json
// Simplified version of the `pluginConfig.json` file
{
  "extensions": [
    {
      "packageName": "@ohif/extension-cornerstone",
      "version": "3.4.0"
    },
    {
      "packageName": "@ohif/extension-measurement-tracking",
      "version": "3.4.0"
    },
    // ...
  ],
  "modes": [
    {
      "packageName": "@ohif/mode-longitudinal",
      "version": "3.4.0"
    }
  ]
}

:::note Important
You SHOULD NOT directly register extensions in the pluginConfig.json file.
Use the provided cli to add/remove/install/uninstall extensions. Read more here
:::

The final registration and import of the extensions happen inside a non-tracked file pluginImport.js (this file is also for internal use only).

After an extension gets registered within the viewer,
each module defined by the extension becomes available to the modes
via the ExtensionManager by requesting it via its id.
Read more about Extension Manager

Lifecycle Hooks

Currently, there are three lifecycle hook for extensions:

preRegistration This hook is called once on
initialization of the entire viewer application, used to initialize the
extensions state, and consume user defined extension configuration. If an
extension defines the preRegistration
lifecycle hook, it is called before any modules are registered in the
ExtensionManager. It's most commonly used to wire up extensions to
services and commands, and to
bootstrap 3rd party libraries.

onModeEnter: This hook is called whenever a new
mode is entered, or a mode’s data or datasource is switched. This hook can be
used to initialize data.

onModeExit: Similarly to onModeEnter, this hook is
called when navigating away from a mode, or before a mode’s data or datasource
is changed. This can be used to cache data for reuse later, but since it
isn't known which mode will be entered next, the state after exiting should be
clean, that is, the same as the state on a clean start. This is called BEFORE
service clean up, and after mode specific onModeExit handling.

Modules

Modules are the meat of extensions, the blocks that we have been talking about
a lot. They provide "definitions", components, and filtering/mapping logic that
are then made available to modes and services.

Each module type has a special purpose, and is consumed by our viewer
differently.

Types Description
LayoutTemplate Control Layout of a route
DataSource Control the mapping from DICOM metadata to OHIF-metadata
SOPClassHandler Determines how retrieved study data is split into "DisplaySets"
Panel Adds left or right hand side panels
Viewport Adds a component responsible for rendering a "DisplaySet"
Commands Adds named commands, scoped to a context, to the CommandsManager
Toolbar Adds buttons or custom components to the toolbar
Context Shared state for a workflow or set of extension module definitions
HangingProtocol Adds hanging protocol rules
Utility Expose utility functions to the outside of extensions

<span style={{"textAlign": 'center', 'fontStyle': 'italic'}}>Tbl. Module types
with abridged descriptions and examples. Each module links to a dedicated
documentation page.

Contexts

The @ohif/app tracks "active contexts" that extensions can use to scope
their functionality. Some example contexts being:

  • Route: ROUTE:VIEWER, ROUTE:STUDY_LIST
  • Active Viewport: ACTIVE_VIEWPORT:CORNERSTONE, ACTIVE_VIEWPORT:VTK

An extension module can use these to say "Only show this Toolbar Button if the
active viewport is a Cornerstone viewport." This helps us use the appropriate UI
and behaviors depending on the current contexts.

For example, if we have hotkey that "rotates the active viewport", each Viewport
module that supports this behavior can add a command with the same name, scoped
to the appropriate context. When the command is fired, the "active contexts"
are used to determine the appropriate implementation of the rotation behavior.


Platform Docs Versioned Docs Version 3.11 Platform Hooks Index (`platform/docs/versioned_docs/version-3.11/platform/hooks/index.md`)


title: Hooks summary: List of React hooks available in the platform, these are custom hooks that are used to access the state of the platform

Hooks

[useMeasurements](./useMeasurements.md)

A React hook that provides mapped measurements from the measurement service with automatic updates when measurements change.

[useViewportSegmentations](./useViewportSegmentations.md)

A React hook that provides segmentation data and representations for the active viewport with automatic updates when segmentations change.

[useMeasurementTracking](./useMeasurementTracking.md)

A React hook that provides measurement tracking information for a specific viewport, including tracking state and tracked measurement UIDs.

[useViewportDisplaySets](./useViewportDisplaySets.md)

A React hook that provides access to display sets associated with a viewport, including background, foreground, overlay, and potential display sets.

[useViewportHover](./useViewportHover.md)

A React hook that tracks mouse hover state and active status for a specific viewport.

[usePatientInfo](./usePatientInfo.md)

A React hook that provides patient information from the active display sets and detects when multiple patients are loaded.

[useSearchParams](./useSearchParams.md)

A React hook that provides access to URL search parameters from both the query string and hash fragment.

[useDynamicMaxHeight](./useDynamicMaxHeight.md)

A React hook that calculates the maximum height for an element based on its position in the viewport, with automatic recalculation on window resize or data changes.

[useSessionStorage](./useSessionStorage.md)

A React hook that provides sessionStorage access with automatic JSON parsing/stringifying and an option to clear data when the page unloads.


Platform Docs Versioned Docs Version 3.11 Platform Managers Index (`platform/docs/versioned_docs/version-3.11/platform/managers/index.md`)


Managers

Overview

OHIF uses Managers to accomplish various purposes such as registering new
services, dependency injection, and aggregating and exposing extension
features.

OHIF-v3 provides the following managers which we will discuss in depth.

Manager Description
Extension Manager Aggregating and exposing modules and features through out the app
Services Manager Single point of registration for all internal and external services
Commands Manager Register commands with specific context and run commands in the app
Hotkeys Manager For keyboard keys assignment to commands

Platform Docs Versioned Docs Version 3.11 Platform Modes Index (`platform/docs/versioned_docs/version-3.11/platform/modes/index.md`)


Modes

Overview

A mode can be thought of as a viewer app configured to perform a specific task,
such as tracking measurements over time, 3D segmentation, a guided radiological
workflow, etc. Addition of modes enables application with many applications
as each mode become a mini app configuration behind the scene.

Upon initialization the viewer will consume extensions and modes and build up
the route desired, these can then be accessed via the study list, or directly
via url parameters.

OHIF-v3 architecture can be seen in the following:

Note: Templates are now a part of “extensions” Routes are configured by modes
and/or app

As mentioned, modes are tied to a specific route in the viewer, and multiple
modes/routes can be present within a single application. This allows for
tremendously more flexibility than before you can now:

  • Simultaneously host multiple viewers with for different use cases from within
    the same app deploy.
  • Make radiological viewers for specific purposes/workflows, e.g.:
    • Tracking the size of lesions over time.
    • PET/CT fusion workflows.
    • Guided review workflows optimized for a specific clinical trial.
  • Still host one single feature-rich viewer if you desire.

Anatomy

A mode configuration has a route name which is dynamically transformed into a
viewer route on initialization of the application. Modes that are available to a
study will appear in the study list.

The mode configuration specifies which extensions the mode requires, which
LayoutTemplate to use, and what props to pass to the template. For the default
template this defines which side panels will be available, as well as what
viewports and which displaySets they may hang.

Mode's config is composed of three elements:

  • id: the mode id
  • modeFactory: the function that returns the mode specific configuration
  • extensionDependencies: the list of extensions that the mode requires

that return a config object with certain
properties, the high-level view of this config object is:

js title="modes/example/src/index.js"
function modeFactory() {
  return {
    id: '',
    version: '',
    displayName: '',
    onModeEnter: () => {},
    onModeExit: () => {},
    validationTags: {},
    isValidMode: () => {},
    routes: [
      {
        path: '',
        init: () => {},
        layoutTemplate: () => {},
      },
    ],
    extensions: extensionDependencies,
    hangingProtocol: [],
    sopClassHandlers: [],
    hotkeys: []
  };
}

const mode = {
  id,
  modeFactory,
  extensionDependencies,
};

export default mode;
Property Description
id unique mode id used to refer to the mode
displayName actual name of the mode being displayed for each study in the study summary panel
onModeEnter hook is called when the mode is entered by the specified route
onModeExit hook is called when the mode exited
validationTags validationTags
isValidMode Checks if the mode is valid for a study
routes route config which defines the route address, and the layout for it
extensionDependencies extensions needed by the mode
hanging protocol list of hanging protocols that the mode should have access to
sopClassHandlers list of SOPClass modules needed by the mode
hotkeys hotkeys

Consuming Extensions

As mentioned in the Extensions section, in OHIF-v3
developers write their extensions to create reusable functionalities that later
can be used by modes. Now, it is time to describe how the registered
extensions will get utilized for a workflow mode via its id.

Each mode has a list of its extensions dependencies which are the
the extension name and version number. In addition, to use a module element you can use the
${extensionId}.${moduleType}.${element.name} schema. For instance, if a mode
requires the left panel with name of AIPanel that is added by the
myAIExtension via the following getPanelModule code, it should address it as
myAIExtension.panelModule.AIPanel inside the mode configuration file. In the
background OHIF will handle grabbing the correct panel via ExtensionManager.

js title="extensions/myaiextension/getpanelmodule.js"
import PanelAI from './PanelAI.js';

function getPanelModule({
  commandsManager,
  extensionManager,
  servicesManager,
}) {
  const wrappedAIPanel = () => {
    return (
      
    );
  };

  return [
    {
      name: 'AIPanel',
      iconName: 'list-bullets',
      iconLabel: '',
      label: 'AI Panel',
      isDisabled: studies => {}, // optional
      component: wrappedAIPanel,
    },
  ];
}

Now, let's look at a simplified code of the basic viewer mode which consumes various functionalities
from different extensions.

js
const extensionDependencies = {
  '@ohif/extension-default': '^3.0.0',
  '@ohif/extension-cornerstone': '^3.0.0',
  '@ohif/extension-measurement-tracking': '^3.0.0',
};

const id = 'viewer';
const version = '3.0.0';

function modeFactory({ modeConfiguration }) {
  return {
    id,
    // ...
    routes: [
      {
        // ...
        layoutTemplate: ({ location, servicesManager }) => {
          return {
            id: ohif.layout,
            props: {
              leftPanels: ['@ohif/extension-measurement-tracking.panelModule.seriesList'],
              rightPanels: ['@ohif/extension-measurement-tracking.panelModule.trackedMeasurements'],
              viewports: [
                {
                  namespace: '@ohif/extension-measurement-tracking.viewportModule.cornerstone-tracked',
                  displaySetsToDisplay: ['@ohif/extension-default.sopClassHandlerModule.stack'],
                },
              ],
            },
          };
        },
      },
    ],
    extensions: extensionDependencies,
    hangingProtocol: ['@ohif/extension-default.hangingProtocolModule.petCT'],
    sopClassHandlers: ['@ohif/extension-default.sopClassHandlerModule.stack'],
    // ...
  };
}

const mode = {
  id,
  modeFactory,
  extensionDependencies,
}

export default mode

Routes

routes config is an array of route settings, and the overall look and behavior
of the viewer at the designated route is defined by the layoutTemplate and
init functions for the route. We will learn more about each of the above
properties inside the route documentation

HangingProtocols

Currently, you can pass your defined hanging protocols inside the
hangingProtocols property of the mode's config. If you specify the hanging protocol
explicitly by its name (only string and not array), it will be THE hanging protocol
that the mode runs with. However, if you specify an array of hanging protocols,
they will get ranked based on the displaySetSelector requirements and the winner
will be the hanging protocol that the mode runs with.

SopClassHandlers

Mode's configuration also accepts the sopClassHandler modules that have been
added by the extensions. This information will get used to initialize DisplaySetService with the provided SOPClass modules which
handles creation of the displaySets.

Hotkeys

hotkeys is another property in the configuration of a mode that can be defined
to add the specific hotkeys to the viewer on the mode route. Additionally, the
name under which the hotkeys are stored can be configured as hotkeyName.
This allows user customization of the mode specific hotkeys.

js
// default hotkeys
import { utils } from '@ohif/ui';

const { hotkeys } = utils;

const myHotkeys = [
  {
    commandName: 'setToolActive',
    commandOptions: { toolName: 'Zoom' },
    label: 'Zoom',
    keys: ['z'],
    isEditable: true,
  },
  {
    commandName: 'scaleUpViewport',
    label: 'Zoom In',
    keys: ['+'],
    isEditable: true,
  },
]

function modeFactory() {
  return {
    id: '',
    id: '',
    displayName: '',
    /*
    ...
    */
    hotkeys: {
      // The name in preferences to use for this set of hotkeys
      // Allows defining different sets for different modes
      name: 'custom-hotkey-name',
      // And the actual custom values here.
      hotkeys:[..hotkeys.defaults.hotkeyBindings, ...myHotkeys]
    },
  }
}

// exports

Registration

Similar to extension registration, viewer will look inside the pluginConfig.json to
find the modes to register.

js title=platform/app/pluginconfig.json
// Simplified version of the `pluginConfig.json` file
{
  "extensions": [
    {
      "packageName": "@ohif/extension-cornerstone",
      "version": "3.4.0"
    },
    // ...
  ],
  "modes": [
    {
      "packageName": "@ohif/mode-longitudinal",
      "version": "3.4.0"
    }
  ]
}

:::note Important
You SHOULD NOT directly register modes in the pluginConfig.json file.
Use the provided cli to add/remove/install/uninstall modes. Read more here
:::

The final registration and import of the modes happen inside a non-tracked file pluginImport.js (this file is also for internal use only).

:::note
You can stack multiple panel components on top of each other by providing an array of panel components in the rightPanels or leftPanels properties.

For instance we can use

text
rightPanels: [[dicomSeg.panel, tracked.measurements], [dicomSeg.panel, tracked.measurements]]

This will result in two panels, one with dicomSeg.panel and tracked.measurements and the other with dicomSeg.panel and tracked.measurements stacked on top of each other.

:::


Platform Docs Versioned Docs Version 3.11 Platform Services Index (`platform/docs/versioned_docs/version-3.11/platform/services/index.md`)


Services

Overview

Services are "concern-specific" code modules that can be consumed across layers.
Services provide a set of operations, often tied to some shared state, and are
made available to through out the app via the ServicesManager. Services are
particularly well suited to address cross-cutting
concerns
.

Each service should be:

  • self-contained
  • able to fail and/or be removed without breaking the application
  • completely interchangeable with another module implementing the same interface

In OHIF-v3 we have added multiple non-UI services and have introduced
pub/sub pattern to reduce coupling between layers.

Read more about Pub/Sub

Services

The following services is available in the OHIF-v3.

Service Type Description
DicomMetadataStore Data Service DicomMetadataStore
DisplaySetService Data Service DisplaySetService
segmentationService Segmentation Service segmentationService
HangingProtocolService Data Service HangingProtocolService
MeasurementService (MODIFIED) Data Service MeasurementService
ToolBarService Data Service ToolBarService
ViewportGridService UI Service ViewportGridService
Cine Service UI Service cine
CustomizationService UI Service customizationService
UIDialogService UI Service UIDialogService
UIModalService UI Service UIModalService
UINotificationService UI Service UINotificationService
UIViewportDialogService UI Service UIViewportDialogService

Platform Docs Versioned Docs Version 3.11 User Guide Viewer Index (`platform/docs/versioned_docs/version-3.11/user-guide/viewer/index.md`)


Overview

When you open a mode, viewport, toolbar and panels of the mode get shown.
It is important to note that each mode has a different UI, which serves its purpose.
Here we explain various components of Basic Viewer mode which includes measurement
tracking functionalities.

Basic viewer mode (longitudinal):

Let's break different aspects of the viewer to the main components:

  • Left Panel (study panel): displays series thumbnails with series details
  • Viewport: renders the image and displays annotations
  • Right Panel (measurements): displays annotations details
  • Toolbar: displays tools and logo

Now, we explain each component and its sub-elements in detail.


Platform Docs Versioned Docs Version 3.11 Migration Guide 3p8 To 3p9 1 Segmentation Index (`platform/docs/versioned_docs/version-3.11/migration-guide/3p8-to-3p9/1-segmentation/index.md`)


id: segmentation-index title: Segmentation sidebar_position: 1 summary: Migration guide for segmentation architecture changes in OHIF 3.9, covering the shift from tool group-centric to viewport-centric architecture to support advanced visualization capabilities and more flexible segmentation handling.

import DocCardList from '@theme/DocCardList';

:::info
This migration involves significant architectural changes to the segmentation system. While we typically aim for incremental updates, the shift from a tool group-centric to a viewport-centric architecture was necessary to support OHIF 3.9's advanced visualization capabilities, and more flexible segmentation handling.

Don't worry - we'll guide you through each change step by step!
:::


Platform Docs Versioned Docs Version 3.11 Migration Guide 3p9 To 3p10 2 CustomizationService Index (`platform/docs/versioned_docs/version-3.11/migration-guide/3p9-to-3p10/2-CustomizationService/index.md`)


CustomizationService

Key Changes:

  1. Unified Customization Getter:

    • The getCustomization method now uniformly retrieves customizations, prioritizing global, then mode, and finally default customizations.
    • The defaultValue parameter in getCustomization is no longer used for setting defaults. It simply returns if no customization is found.
    • The methods getModeCustomization and getGlobalCustomization are deprecated.
  2. Simplified Customization Registration:

    • The customizationType property in customization definitions is renamed to inheritsFrom.

    • The merge property in customization definitions is removed. Instead, a customization is merged using the helper methods. The basic update commands are listed in the table below, and you can learn more about the helper methods here.

      Command Description Example
      $set Replace a value entirely Replace a list or object
      $push Append items to an array Add to the end of a list
      $unshift Prepend items to an array Add to the start of a list
      $splice Insert, remove, or replace at specific index Modify specific indices in a list
      $merge Update specific fields in an object Change a subset of fields
      $apply Compute the new value dynamically Apply a function to transform values
      $filter Find and update specific items in arrays Target nested structures based on matching criteria
  3. New $transform command:

    • If you were using the transform command, you should now use the $transform command. Just a simple rename to make it more consistent with the other commands.
  4. Renamed CornerstoneOverlay customizations:

    • The cornerstoneOverlay customizations (cornerstoneOverlayTopLeft, cornerstoneOverlayTopRight, cornerstoneOverlayBottomLeft, cornerstoneOverlayBottomRight) have been renamed to viewportOverlay.topLeft, viewportOverlay.topRight, viewportOverlay.bottomLeft, and viewportOverlay.bottomRight. See dedicated page for customizing viewport overlays here.
  5. Renamed customRoutes:

    • The customRoutes customization is renamed to routes.customRoutes.
  6. contextMenu customization:

    • The contextMenu customization now uses the inheritsFrom property to inherit from other context menus, previously it was called customizationType
  7. New immutability-helper dependency:
    The immutability-helper library is now used for merging customizations. If you encounter an error related to it, you'll need to install it - though OHIF should really handle the installation for you, so this is pretty much just a heads up.

Migration Steps:

  1. Replace getModeCustomization and getGlobalCustomization with getCustomization:

    • Before:

      javascript
      const tools = customizationService.getModeCustomization(
        'cornerstone.overlayViewportTools'
      )?.tools;
      const globalValue = customizationService.getGlobalCustomization('someGlobalKey');
    • After:

      javascript
      const tools = customizationService.getCustomization('cornerstone.overlayViewportTools');
      const globalValue = customizationService.getCustomization('someGlobalKey');

      :::note
      The returned value is the actual customization value, not an object that needs to be broken down.
      :::

  2. Update Customization Definitions:

    • We've moved away from using random items in the customization definition, and now we use the id property to identify the customization as a value. Previously, it was referred to as value, values, and so on, but now an id is used to reference the customization. This approach really simplifies things - when you need to grab the customization, you can just use the id to get it, and you don't have to bother with destructuring the value from the object.

Example: Customizing a Panel

Before (v3.9):

javascript
// the default value was hardcoded inside the panel itself - bad idea!
// default was given in the panel itself

// PanelSegmentation.tsx

// Retrieve the onSegmentationAdd customization
const { onSegmentationAdd } = customizationService.getCustomization(
  'PanelSegmentation.onSegmentationAdd',
  {
    id: 'segmentation.onSegmentationAdd',
    onSegmentationAdd: handlers.onSegmentationAdd,
  }
);

// Retrieve the disableEditing customization
const { disableEditing } = customizationService.getCustomization(
  'PanelSegmentation.disableEditing',
  {
    id: 'default.disableEditing',
    disableEditing: false,
  }
);



// mode was customizing it via
customizationService.addModeCustomizations([
  {
    id: 'PanelSegmentation.tableMode',
    mode: 'expanded',
  },
  {
    id: 'PanelSegmentation.showAddSegment',
    showAddSegment: false,
  },
]);

After (v3.10):

javascript
// cornerstone extension getCustomizationModule
// centralized customization location for all extensions - good!
function getCustomizationModule() {
  return [
    {
      name: 'default',
      value: {
        'panelSegmentation.disableEditing': false,
        'panelSegmentation.showAddSegment': true,
      },
    },
  ];
}


// inside panelSegmentation.tsx
const disableEditing = customizationService.getCustomization('panelSegmentation.disableEditing');
const showAddSegment = customizationService.getCustomization('panelSegmentation.showAddSegment');


// mode can customize it via $ operators for mode customizations
customizationService.setCustomizations({
  'panelSegmentation.disableEditing': { $set: true },
  'panelSegmentation.showAddSegment': { $set: false },
});


//or via configuration for global customizations
window.config = {
  // rest of config
  customizationService: [
    {
      'panelSegmentation.disableEditing': {
        $set: true, // Disables editing of segmentations in the panel
      },
    },
  ],
  // rest of config
};

Example: Updating a Customization

Let's say you have a customization in v3.9 that adds a custom overlay item to the top-left corner:

Before (v3.9):

javascript
// In your mode's onModeEnter
customizationService.addModeCustomizations([
  {
    id: 'cornerstoneOverlayTopLeft',
    items: [
      {
        id: 'myCustomOverlay',
        customizationType: 'ohif.overlayItem',
        attribute: 'PatientName',
        label: 'Patient:',
      },
    ],
  },
]);

After (v3.10):

javascript
// In your mode's onModeEnter or elsewhere
customizationService.setCustomizations({
  'viewportOverlay.topLeft': {
    $push: [
      {
        id: 'myCustomOverlay',
        inheritsFrom: 'ohif.overlayItem',
        attribute: 'PatientName',
        label: 'Patient:',
      },
    ],
  },
});
text
**Example: Customizing viewport action Menu**

**Before (v3.9):**

```javascript
// In your configuration for global customizations
window.config = {
    // rest of config
    addWindowLevelActionMenu: true,
};

After (v3.10):

javascript
// you can now handle each action menu item (windowLevelActionMenu and segmentationOverlay) separately

// cornerstone extension getCustomizationModule
function getCustomizationModule() {
    return [
        {
            name: 'default',
            value: {
                'viewportActionMenu.windowLevelActionMenu': {
                    enabled: true,
                    location: viewportActionCornersService.LOCATIONS.topRight,
                },
                'viewportActionMenu.segmentationOverlay': {
                    enabled: true,
                    location: viewportActionCornersService.LOCATIONS.topRight,
                },
            },
        },
    ];
}


// Accessing customizations within your component (e.g., OHIFCornerstoneViewport.tsx)
const windowLevelActionMenu = customizationService.getCustomization('viewportActionMenu.windowLevelActionMenu');
const segmentationOverlay = customizationService.getCustomization('viewportActionMenu.segmentationOverlay');

// Modifying customizations at runtime, for example, in your mode's onModeEnter
customizationService.setCustomizations({
    'viewportActionMenu.windowLevelActionMenu': {
        $set: {
            enabled: false,
            location: viewportActionCornersService.LOCATIONS.bottomLeft,
        },
    },
    'viewportActionMenu.segmentationOverlay': {
        $set: {
            enabled: true,
            location: viewportActionCornersService.LOCATIONS.topLeft,
        },
    },
});

// Alternatively, setting global customizations via configuration
window.config = {
    // rest of config
    customizationService: [
        {
            'viewportActionMenu.windowLevelActionMenu': {
                $set: {
                    enabled: false,
                    location: 1,
                },
            },
            'viewportActionMenu.segmentationOverlay': {
                $set: {
                    enabled: true,
                    location: 1,
                },
            },
        },
    ],
    // rest of config
};

Note:

  • The customizationType is replaced with inheritsFrom.

Renaming

To keep our customization system consistent, you should be aware of a few key renaming conventions. We now follow a straightforward naming convention for customizations: scopeName.customizationItem.

Customization Key (Old) Customization Key (New) Description
PanelMeasurement.disableEditing panelMeasurement.disableEditing Disables editing measurements in the Measurement Panel and after SR hydration.
PanelSegmentation.CustomDropdownMenuContent panelSegmentation.customDropdownMenuContent Custom content for the dropdown menu in the Segmentation Panel.
PanelSegmentation.disableEditing panelSegmentation.disableEditing Disables editing segmentations in the Segmentation Panel.
PanelSegmentation.showAddSegment panelSegmentation.showAddSegment Controls visibility of the "Add Segment" button in the Segmentation Panel.
PanelSegmentation.onSegmentationAdd panelSegmentation.onSegmentationAdd Custom function to execute when a new segmentation is added.
PanelSegmentation.tableMode panelSegmentation.tableMode Controls the table mode (collapsed/expanded) in the Segmentation Panel.
PanelSegmentation.readableText panelSegmentation.readableText Custom readable text labels for the Segmentation Panel.
PanelStudyBrowser.studyMode studyBrowser.studyMode Controls the study mode (all/primary/recent) in the Study Browser Panel.
customRoutes routes.customRoutes Defines custom routes for the application.
cornerstoneOverlayTopLeft viewportOverlay.topLeft Custom overlay items for the top-left corner of the viewport.
cornerstoneOverlayTopRight viewportOverlay.topRight Custom overlay items for the top-right corner of the viewport.
cornerstoneOverlayBottomLeft viewportOverlay.bottomLeft Custom overlay items for the bottom-left corner of the viewport.
cornerstoneOverlayBottomRight viewportOverlay.bottomRight Custom overlay items for the bottom-right corner of the viewport.
(New) viewportActionMenu.windowLevelActionMenu Controls the display and the location of the window level action menu in the viewport.
(New) viewportActionMenu.segmentationOverlay Controls the display and the location of segmentation overlays in the viewport.

Platform Docs Versioned Docs Version 3.11 Platform Services Data Index (`platform/docs/versioned_docs/version-3.11/platform/services/data/index.md`)


Overview

Data services are the first category of services which deal with handling non-ui
related state Each service have their own internal state which they handle.

We have replaced the redux store. Instead, we have introduced various
services and a pub/sub pattern to subscribe and run, which makes the OHIF-v3
architecture nice and clean.

We maintain the following non-ui Services:

Service Architecture

We have explained services and how to create a custom service in the
ServicesManager section of the docs

To recap: The simplest service return a new object that has a name property,
and Create method which instantiate the service class. The "Factory Function"
that creates the service is provided with the implementation (this is slightly
different for UI Services).

js
// extensions/customExtension/src/services/backEndService/index.js
import backEndService from './backEndService';

export default function WrappedBackEndService(servicesManager) {
  return {
    name: 'myService',
    create: ({ configuration = {} }) => {
      return new backEndService(servicesManager);
    },
  };
}

A service, once created, can be registered with the ServicesManager to make it
accessible to extensions. Similarly, the application code can access named
services from the ServicesManager.

Read more of how to design a new custom service and register it


Platform Docs Versioned Docs Version 3.11 Platform Services Ui Index (`platform/docs/versioned_docs/version-3.11/platform/services/ui/index.md`)


Overview

A typical web application will have components and state for common UI like
modals, notifications, dialogs, etc. A UI service makes it possible to leverage
these components from an extension.

We maintain the following UI Services:

Providers for UI services

There are several context providers that wraps the application routes. This
makes the context values exposed in the app, and service's setImplementation
can get run to override the implementation of the service.

js title="platform/app/src/app.jsx"
function App({ config, defaultExtensions }) {
  /**...**/
  /**...**/
  return (
    /**...**/
    <ViewportGridProvider service={ViewportGridService}>
      <ViewportDialogProvider service={UIViewportDialogService}>
        <CineProvider service={CineService}>
          <SnackbarProvider service={UINotificationService}>
            <DialogProvider service={UIDialogService}>
              <ModalProvider modal={Modal} service={UIModalService}>
                {appRoutes}
              </ModalProvider>
            </DialogProvider>
          </SnackbarProvider>
        </CineProvider>
      </ViewportDialogProvider>
    </ViewportGridProvider>
    /**...**/
  );
}

Example

For instance UIModalService has the following Public API:

js title="platform/core/src/services/uimodalservice/index.js"
const publicAPI = {
  name,
  hide: _hide,
  show: _show,
  setServiceImplementation,
};

function setServiceImplementation({
  hide: hideImplementation,
  show: showImplementation,
}) {
  /** ... **/
  serviceImplementation._hide = hideImplementation;
  serviceImplementation._show = showImplementation;
  /** ... **/
}

export default {
  name: 'UIModalService',
  create: ({ configuration = {} }) => {
    return publicAPI;
  },
};

UIModalService implementation can be set (override) in its context provider.
For instance in ModalProvider we have:

text
/* Detailed source-code truncated for AI context efficiency. */

Therefore, anywhere in the app that we have access to react context we can use
it by calling the useModal from @ohif/ui. As a matter of fact, we are
utilizing the modal for the preference window which shows the hotkeys after
clicking on the gear button on the right side of the header.

A simplified code for our worklist is:

js title="platform/app/src/routes/worklist/worklist.jsx"
import { useModal, Header } from '@ohif/ui';

function WorkList({
  history,
  data: studies,
  dataTotal: studiesTotal,
  isLoadingData,
  dataSource,
  hotkeysManager,
}) {
  const { show, hide } = useModal();

  /** ... **/

  const menuOptions = [
    {
      title: t('Header:About'),
      icon: 'info',
      onClick: () => show({ content: AboutModal, title: 'About OHIF Viewer' }),
    },
    {
      title: t('Header:Preferences'),
      icon: 'settings',
      onClick: () =>
        show({
          title: t('UserPreferencesModal:User Preferences'),
          content: UserPreferences,
          contentProps: {
            hotkeyDefaults: hotkeysManager.getValidHotkeyDefinitions(
              hotkeyDefaults
            ),
            hotkeyDefinitions,
            onCancel: hide,
            currentLanguage: currentLanguage(),
            availableLanguages,
            defaultLanguage,
            onSubmit: state => {
              i18n.changeLanguage(state.language.value);
              hotkeysManager.setHotkeys(state.hotkeyDefinitions);
              hide();
            },
            onReset: () => hotkeysManager.restoreDefaultBindings(),
          },
        }),
    },
  ];
  /** ... **/
  return (
    <div>
      /** ... **/
      <Header isSticky menuOptions={menuOptions} isReturnEnabled={false} />
      /** ... **/
    </div>
  );
}

Tips & Tricks

It's important to remember that all we're doing is making it possible to control
bits of the application's UI from an extension. Here are a few non-obvious
takeaways worth mentioning:

  • Your application code should continue to use React context
    (consumers/providers) as it normally would
  • You can substitute our "out of the box" UI implementations with your own
  • You can create and register your own UI services
  • You can choose not to register a service or provide a service implementation
  • In extensions, you can provide fallback/alternative behavior if an expected
    service is not registered
    • No UIModalService? Use the UINotificationService to notify users.
  • You can technically register a service in an extension and expose it to the
    core application

Note: These are recommended patterns, not hard and fast rules. Following them
will help reduce confusion and interoperability with the larger OHIF
community, but they're not silver bullets. Please speak up, create an issue,
if you would like to discuss new services or improvements to this pattern.


Platform Docs CHANGELOG (`platform/docs/CHANGELOG.md`)

Change Log

All notable changes to this project will be documented in this file.
See Conventional Commits for commit guidelines.

[3.13.0-beta.89](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.88...v3.13.0-beta.89) (2026-06-10)

Note: Version bump only for package ohif-docs

[3.13.0-beta.88](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.87...v3.13.0-beta.88) (2026-06-05)

Note: Version bump only for package ohif-docs

[3.13.0-beta.87](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.86...v3.13.0-beta.87) (2026-05-29)

Note: Version bump only for package ohif-docs

[3.13.0-beta.86](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.85...v3.13.0-beta.86) (2026-05-28)

Note: Version bump only for package ohif-docs

[3.13.0-beta.85](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.84...v3.13.0-beta.85) (2026-05-28)

Features

  • WorkList: New Study List (WorkList based on ui-next); old study list renamed to LegacyWorklist (#6005) (daae4c1)

[3.13.0-beta.84](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.83...v3.13.0-beta.84) (2026-05-27)

Note: Version bump only for package ohif-docs

[3.13.0-beta.83](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.82...v3.13.0-beta.83) (2026-05-26)

Note: Version bump only for package ohif-docs

[3.13.0-beta.82](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.81...v3.13.0-beta.82) (2026-05-22)

Note: Version bump only for package ohif-docs

[3.13.0-beta.81](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.80...v3.13.0-beta.81) (2026-05-21)

Note: Version bump only for package ohif-docs

[3.13.0-beta.80](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.79...v3.13.0-beta.80) (2026-05-20)

Note: Version bump only for package ohif-docs

[3.13.0-beta.79](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.78...v3.13.0-beta.79) (2026-05-19)

Note: Version bump only for package ohif-docs

[3.13.0-beta.78](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.77...v3.13.0-beta.78) (2026-05-19)

Note: Version bump only for package ohif-docs

[3.13.0-beta.77](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.76...v3.13.0-beta.77) (2026-05-19)

Note: Version bump only for package ohif-docs

[3.13.0-beta.76](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.75...v3.13.0-beta.76) (2026-05-19)

Note: Version bump only for package ohif-docs

[3.13.0-beta.75](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.74...v3.13.0-beta.75) (2026-05-18)

Note: Version bump only for package ohif-docs

[3.13.0-beta.74](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.73...v3.13.0-beta.74) (2026-05-15)

Note: Version bump only for package ohif-docs

[3.13.0-beta.73](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.72...v3.13.0-beta.73) (2026-05-13)

Note: Version bump only for package ohif-docs

[3.13.0-beta.72](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.71...v3.13.0-beta.72) (2026-05-12)

Note: Version bump only for package ohif-docs

[3.13.0-beta.71](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.70...v3.13.0-beta.71) (2026-05-07)

Note: Version bump only for package ohif-docs

[3.13.0-beta.70](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.69...v3.13.0-beta.70) (2026-05-07)

Note: Version bump only for package ohif-docs

[3.13.0-beta.69](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.68...v3.13.0-beta.69) (2026-05-06)

Note: Version bump only for package ohif-docs

[3.13.0-beta.68](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.67...v3.13.0-beta.68) (2026-05-05)

Bug Fixes

  • ToolGroupService: Centralize tool binding persistence and provide API to add and remove persisted bindings. (#5989) (979d619)

[3.13.0-beta.67](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.66...v3.13.0-beta.67) (2026-04-30)

Note: Version bump only for package ohif-docs

[3.13.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.65...v3.13.0-beta.66) (2026-04-29)

Note: Version bump only for package ohif-docs

[3.13.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.64...v3.13.0-beta.65) (2026-04-29)

Note: Version bump only for package ohif-docs

[3.13.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.63...v3.13.0-beta.64) (2026-04-27)

Note: Version bump only for package ohif-docs

[3.13.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.62...v3.13.0-beta.63) (2026-04-27)

Bug Fixes

  • security: refine dynamic config URL trust policy and document trusted-origin behavior (#5973) (f3cca21)

[3.13.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.61...v3.13.0-beta.62) (2026-04-23)

Note: Version bump only for package ohif-docs

[3.13.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.60...v3.13.0-beta.61) (2026-04-23)

Features

  • slice scrollbar: Integrate ViewportSliceProgressScrollbar with customizations and docs (#5960) (8fc0dc1)

[3.13.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.59...v3.13.0-beta.60) (2026-04-21)

Bug Fixes

  • configuration: Harden dynamic datasource URL trust boundaries and credential handling. (#5963) (eede569)

[3.13.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.58...v3.13.0-beta.59) (2026-04-16)

Note: Version bump only for package ohif-docs

[3.13.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.57...v3.13.0-beta.58) (2026-04-14)

Note: Version bump only for package ohif-docs

[3.13.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.56...v3.13.0-beta.57) (2026-04-13)

Note: Version bump only for package ohif-docs

[3.13.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.55...v3.13.0-beta.56) (2026-04-10)

Note: Version bump only for package ohif-docs

[3.13.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.54...v3.13.0-beta.55) (2026-04-10)

Note: Version bump only for package ohif-docs

[3.13.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.53...v3.13.0-beta.54) (2026-04-08)

Note: Version bump only for package ohif-docs

[3.13.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.52...v3.13.0-beta.53) (2026-04-06)

Note: Version bump only for package ohif-docs

[3.13.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.51...v3.13.0-beta.52) (2026-04-06)

Note: Version bump only for package ohif-docs

[3.13.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.50...v3.13.0-beta.51) (2026-04-03)

Note: Version bump only for package ohif-docs

[3.13.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.49...v3.13.0-beta.50) (2026-04-02)

Note: Version bump only for package ohif-docs

[3.13.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.48...v3.13.0-beta.49) (2026-04-02)

Note: Version bump only for package ohif-docs

[3.13.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.47...v3.13.0-beta.48) (2026-04-01)

Note: Version bump only for package ohif-docs

[3.13.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.46...v3.13.0-beta.47) (2026-03-28)

Note: Version bump only for package ohif-docs

[3.13.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.45...v3.13.0-beta.46) (2026-03-27)

Note: Version bump only for package ohif-docs

[3.13.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.44...v3.13.0-beta.45) (2026-03-27)

Note: Version bump only for package ohif-docs

[3.13.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.43...v3.13.0-beta.44) (2026-03-27)

Note: Version bump only for package ohif-docs

[3.13.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.42...v3.13.0-beta.43) (2026-03-17)

Note: Version bump only for package ohif-docs

[3.13.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.41...v3.13.0-beta.42) (2026-03-17)

Features

[3.13.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.40...v3.13.0-beta.41) (2026-03-16)

Note: Version bump only for package ohif-docs

[3.13.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.39...v3.13.0-beta.40) (2026-03-13)

Note: Version bump only for package ohif-docs

[3.13.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.38...v3.13.0-beta.39) (2026-03-13)

Note: Version bump only for package ohif-docs

[3.13.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.37...v3.13.0-beta.38) (2026-03-12)

Note: Version bump only for package ohif-docs

[3.13.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.36...v3.13.0-beta.37) (2026-03-12)

Note: Version bump only for package ohif-docs

[3.13.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.35...v3.13.0-beta.36) (2026-03-11)

Note: Version bump only for package ohif-docs

[3.13.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.34...v3.13.0-beta.35) (2026-03-09)

Note: Version bump only for package ohif-docs

[3.13.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.33...v3.13.0-beta.34) (2026-03-09)

Note: Version bump only for package ohif-docs

[3.13.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.32...v3.13.0-beta.33) (2026-03-05)

Bug Fixes

  • security: Bump svgo and tar to fix vulnerabilities. (#5877) (61a1fcc)

[3.13.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.31...v3.13.0-beta.32) (2026-03-05)

Note: Version bump only for package ohif-docs

[3.13.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.30...v3.13.0-beta.31) (2026-03-04)

Note: Version bump only for package ohif-docs

[3.13.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.29...v3.13.0-beta.30) (2026-03-04)

Note: Version bump only for package ohif-docs

[3.13.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.28...v3.13.0-beta.29) (2026-03-04)

Bug Fixes

  • security: Address various security vulnerabilities. (#5869) (be8e266)

[3.13.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.27...v3.13.0-beta.28) (2026-03-03)

Note: Version bump only for package ohif-docs

[3.13.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.26...v3.13.0-beta.27) (2026-03-02)

Note: Version bump only for package ohif-docs

[3.13.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.25...v3.13.0-beta.26) (2026-02-28)

Note: Version bump only for package ohif-docs

[3.13.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.24...v3.13.0-beta.25) (2026-02-26)

Note: Version bump only for package ohif-docs

[3.13.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.23...v3.13.0-beta.24) (2026-02-24)

Note: Version bump only for package ohif-docs

[3.13.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.22...v3.13.0-beta.23) (2026-02-23)

Note: Version bump only for package ohif-docs

[3.13.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.21...v3.13.0-beta.22) (2026-02-23)

Note: Version bump only for package ohif-docs

[3.13.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.20...v3.13.0-beta.21) (2026-02-23)

Note: Version bump only for package ohif-docs

[3.13.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.19...v3.13.0-beta.20) (2026-02-21)

Note: Version bump only for package ohif-docs

[3.13.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.18...v3.13.0-beta.19) (2026-02-20)

Note: Version bump only for package ohif-docs

[3.13.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.17...v3.13.0-beta.18) (2026-02-19)

Bug Fixes

  • segmentation overlay: update viewport ds list upon seg delete - OHIF-2425 (#5729) (b353541)

[3.13.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.16...v3.13.0-beta.17) (2026-02-19)

Note: Version bump only for package ohif-docs

[3.13.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.15...v3.13.0-beta.16) (2026-02-18)

Bug Fixes

  • security: Bump tar to 7.5.9 and lerna to 9.0.4 to fix CVE-2026-26960. (#5824) (3d59c0d)

[3.13.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.14...v3.13.0-beta.15) (2026-02-17)

Note: Version bump only for package ohif-docs

[3.13.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.13...v3.13.0-beta.14) (2026-02-13)

Note: Version bump only for package ohif-docs

[3.13.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.12...v3.13.0-beta.13) (2026-02-12)

Bug Fixes

  • colors: Replace hardcoded black with background color token (#5815) (dbc31a5)

[3.13.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.11...v3.13.0-beta.12) (2026-02-12)

Note: Version bump only for package ohif-docs

[3.13.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.10...v3.13.0-beta.11) (2026-02-12)

Note: Version bump only for package ohif-docs

[3.13.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.9...v3.13.0-beta.10) (2026-02-11)

Note: Version bump only for package ohif-docs

[3.13.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.9) (2026-02-11)

Note: Version bump only for package ohif-docs

[3.13.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.8) (2026-02-11)

Note: Version bump only for package ohif-docs

[3.13.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.6...v3.13.0-beta.7) (2026-02-10)

Note: Version bump only for package ohif-docs

[3.13.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.5...v3.13.0-beta.6) (2026-02-10)

Note: Version bump only for package ohif-docs

[3.13.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.4...v3.13.0-beta.5) (2026-02-10)

Note: Version bump only for package ohif-docs

[3.13.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.3...v3.13.0-beta.4) (2026-02-10)

Bug Fixes

[3.13.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.2...v3.13.0-beta.3) (2026-02-10)

Note: Version bump only for package ohif-docs

[3.13.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.1...v3.13.0-beta.2) (2026-02-10)

Bug Fixes

  • cine: prevent crash on second view/hydration of SR series (#5724) (f70c9b9)

[3.13.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.13.0-beta.0...v3.13.0-beta.1) (2026-02-09)

Note: Version bump only for package ohif-docs

[3.13.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.135...v3.13.0-beta.0) (2026-02-07)

Note: Version bump only for package ohif-docs

[3.12.0-beta.135](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.134...v3.12.0-beta.135) (2026-02-05)

Note: Version bump only for package ohif-docs

[3.12.0-beta.134](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.133...v3.12.0-beta.134) (2026-02-05)

Note: Version bump only for package ohif-docs

[3.12.0-beta.133](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.132...v3.12.0-beta.133) (2026-02-04)

Note: Version bump only for package ohif-docs

[3.12.0-beta.132](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.131...v3.12.0-beta.132) (2026-01-30)

Note: Version bump only for package ohif-docs

[3.12.0-beta.131](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.130...v3.12.0-beta.131) (2026-01-30)

Note: Version bump only for package ohif-docs

[3.12.0-beta.130](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.129...v3.12.0-beta.130) (2026-01-28)

Note: Version bump only for package ohif-docs

[3.12.0-beta.129](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.128...v3.12.0-beta.129) (2026-01-27)

Note: Version bump only for package ohif-docs

[3.12.0-beta.128](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.127...v3.12.0-beta.128) (2026-01-27)

Note: Version bump only for package ohif-docs

[3.12.0-beta.127](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.126...v3.12.0-beta.127) (2026-01-22)

Bug Fixes

[3.12.0-beta.126](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.125...v3.12.0-beta.126) (2026-01-22)

Note: Version bump only for package ohif-docs

[3.12.0-beta.125](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.124...v3.12.0-beta.125) (2026-01-21)

Note: Version bump only for package ohif-docs

[3.12.0-beta.124](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.123...v3.12.0-beta.124) (2026-01-16)

Bug Fixes

  • microscopy: Update microscope to 0.48.17 to fix a measurement exception. (#5710) (4a1f509)

[3.12.0-beta.123](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.122...v3.12.0-beta.123) (2026-01-14)

Note: Version bump only for package ohif-docs

[3.12.0-beta.122](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.121...v3.12.0-beta.122) (2026-01-13)

Note: Version bump only for package ohif-docs

[3.12.0-beta.121](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.120...v3.12.0-beta.121) (2026-01-12)

Note: Version bump only for package ohif-docs

[3.12.0-beta.120](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.119...v3.12.0-beta.120) (2026-01-09)

Note: Version bump only for package ohif-docs

[3.12.0-beta.119](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.118...v3.12.0-beta.119) (2026-01-08)

Note: Version bump only for package ohif-docs

[3.12.0-beta.118](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.117...v3.12.0-beta.118) (2026-01-07)

Note: Version bump only for package ohif-docs

[3.12.0-beta.117](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.116...v3.12.0-beta.117) (2026-01-06)

Note: Version bump only for package ohif-docs

[3.12.0-beta.116](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.115...v3.12.0-beta.116) (2026-01-06)

Note: Version bump only for package ohif-docs

[3.12.0-beta.115](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.114...v3.12.0-beta.115) (2026-01-05)

Note: Version bump only for package ohif-docs

[3.12.0-beta.114](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.113...v3.12.0-beta.114) (2026-01-05)

Bug Fixes

  • security: update qs package to fix vulnerability CVE-2025-15284 (#5686) (ca364a3)

[3.12.0-beta.113](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.112...v3.12.0-beta.113) (2025-12-19)

Note: Version bump only for package ohif-docs

[3.12.0-beta.112](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.111...v3.12.0-beta.112) (2025-12-19)

Note: Version bump only for package ohif-docs

[3.12.0-beta.111](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.110...v3.12.0-beta.111) (2025-12-18)

Note: Version bump only for package ohif-docs

[3.12.0-beta.110](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.109...v3.12.0-beta.110) (2025-12-18)

Note: Version bump only for package ohif-docs

[3.12.0-beta.109](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.108...v3.12.0-beta.109) (2025-12-18)

Note: Version bump only for package ohif-docs

[3.12.0-beta.108](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.107...v3.12.0-beta.108) (2025-12-17)

Note: Version bump only for package ohif-docs

[3.12.0-beta.107](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.106...v3.12.0-beta.107) (2025-12-16)

Note: Version bump only for package ohif-docs

[3.12.0-beta.106](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.105...v3.12.0-beta.106) (2025-12-16)

Note: Version bump only for package ohif-docs

[3.12.0-beta.105](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.104...v3.12.0-beta.105) (2025-12-15)

Note: Version bump only for package ohif-docs

[3.12.0-beta.104](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.103...v3.12.0-beta.104) (2025-12-12)

Note: Version bump only for package ohif-docs

[3.12.0-beta.103](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.102...v3.12.0-beta.103) (2025-12-12)

Note: Version bump only for package ohif-docs

[3.12.0-beta.102](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.101...v3.12.0-beta.102) (2025-12-10)

Note: Version bump only for package ohif-docs

[3.12.0-beta.101](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.100...v3.12.0-beta.101) (2025-12-09)

Note: Version bump only for package ohif-docs

[3.12.0-beta.100](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.99...v3.12.0-beta.100) (2025-12-05)

Features

  • notification: add custom notification component support (#5605) (c4e5a46)

[3.12.0-beta.99](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.98...v3.12.0-beta.99) (2025-12-04)

Bug Fixes

[3.12.0-beta.98](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.97...v3.12.0-beta.98) (2025-12-03)

Note: Version bump only for package ohif-docs

[3.12.0-beta.97](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.96...v3.12.0-beta.97) (2025-12-03)

Note: Version bump only for package ohif-docs

[3.12.0-beta.96](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.95...v3.12.0-beta.96) (2025-12-02)

Note: Version bump only for package ohif-docs

[3.12.0-beta.95](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.94...v3.12.0-beta.95) (2025-12-02)

Note: Version bump only for package ohif-docs

[3.12.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.93...v3.12.0-beta.94) (2025-12-02)

Note: Version bump only for package ohif-docs

[3.12.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.92...v3.12.0-beta.93) (2025-11-25)

Note: Version bump only for package ohif-docs

[3.12.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.91...v3.12.0-beta.92) (2025-11-24)

Note: Version bump only for package ohif-docs

[3.12.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.90...v3.12.0-beta.91) (2025-11-21)

Note: Version bump only for package ohif-docs

[3.12.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.89...v3.12.0-beta.90) (2025-11-21)

Note: Version bump only for package ohif-docs

[3.12.0-beta.89](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.88...v3.12.0-beta.89) (2025-11-20)

Note: Version bump only for package ohif-docs

[3.12.0-beta.88](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.87...v3.12.0-beta.88) (2025-11-20)

Note: Version bump only for package ohif-docs

[3.12.0-beta.87](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.86...v3.12.0-beta.87) (2025-11-19)

Bug Fixes

  • SegmentationStyle: Fix inactive contour visibility and styling. (#5563) (5c17c26)

[3.12.0-beta.86](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.85...v3.12.0-beta.86) (2025-11-13)

Note: Version bump only for package ohif-docs

[3.12.0-beta.85](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.84...v3.12.0-beta.85) (2025-11-11)

Bug Fixes

  • interpolation: Auto accept interpolation when the interpolation process is completed. (#5555) (834ae3c)

[3.12.0-beta.84](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.83...v3.12.0-beta.84) (2025-11-10)

Note: Version bump only for package ohif-docs

[3.12.0-beta.83](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.82...v3.12.0-beta.83) (2025-11-06)

Note: Version bump only for package ohif-docs

[3.12.0-beta.82](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.81...v3.12.0-beta.82) (2025-11-05)

Note: Version bump only for package ohif-docs

[3.12.0-beta.81](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.80...v3.12.0-beta.81) (2025-11-05)

Bug Fixes

  • SegmentationTools: [Bug] Changes of brush/eraser radius with hotkey do not reflect on segmentation tool (#5535) (29bd87c)

[3.12.0-beta.80](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.79...v3.12.0-beta.80) (2025-11-05)

Note: Version bump only for package ohif-docs

[3.12.0-beta.79](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.78...v3.12.0-beta.79) (2025-10-30)

Bug Fixes

  • security: Exact versioning and docs dependabot alerts (#5536) (000e42e)

[3.12.0-beta.78](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.77...v3.12.0-beta.78) (2025-10-29)

Note: Version bump only for package ohif-docs

[3.12.0-beta.77](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.76...v3.12.0-beta.77) (2025-10-28)

Note: Version bump only for package ohif-docs

[3.12.0-beta.76](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.75...v3.12.0-beta.76) (2025-10-27)

Note: Version bump only for package ohif-docs

[3.12.0-beta.75](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.74...v3.12.0-beta.75) (2025-10-24)

Bug Fixes

  • security: For bun, enforce frozen lockfile. For yarn, strongly suggest using frozen lockfile. (#5508) (1009c60)

[3.12.0-beta.74](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.73...v3.12.0-beta.74) (2025-10-23)

Note: Version bump only for package ohif-docs

[3.12.0-beta.73](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.72...v3.12.0-beta.73) (2025-10-22)

Note: Version bump only for package ohif-docs

[3.12.0-beta.72](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.71...v3.12.0-beta.72) (2025-10-22)

Note: Version bump only for package ohif-docs

[3.12.0-beta.71](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.70...v3.12.0-beta.71) (2025-10-21)

Note: Version bump only for package ohif-docs

[3.12.0-beta.70](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.69...v3.12.0-beta.70) (2025-10-20)

Note: Version bump only for package ohif-docs

[3.12.0-beta.69](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.68...v3.12.0-beta.69) (2025-10-20)

Note: Version bump only for package ohif-docs

[3.12.0-beta.68](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.67...v3.12.0-beta.68) (2025-10-18)

Note: Version bump only for package ohif-docs

[3.12.0-beta.67](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.66...v3.12.0-beta.67) (2025-10-17)

Bug Fixes

  • ErrorBoundary: Allow for details to be shown in production. (#5504) (4620cc3)

[3.12.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.65...v3.12.0-beta.66) (2025-10-17)

Note: Version bump only for package ohif-docs

[3.12.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.64...v3.12.0-beta.65) (2025-10-17)

Note: Version bump only for package ohif-docs

[3.12.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.63...v3.12.0-beta.64) (2025-10-15)

Note: Version bump only for package ohif-docs

[3.12.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.62...v3.12.0-beta.63) (2025-10-15)

Note: Version bump only for package ohif-docs

[3.12.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.61...v3.12.0-beta.62) (2025-10-15)

Note: Version bump only for package ohif-docs

[3.12.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.60...v3.12.0-beta.61) (2025-10-15)

Bug Fixes

[3.12.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.59...v3.12.0-beta.60) (2025-10-15)

Note: Version bump only for package ohif-docs

[3.12.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.58...v3.12.0-beta.59) (2025-10-14)

Bug Fixes

  • security: Use exact versioning for dependencies in package.json files. (#5494) (c7d2017)

[3.12.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.57...v3.12.0-beta.58) (2025-10-14)

Note: Version bump only for package ohif-docs

[3.12.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.56...v3.12.0-beta.57) (2025-10-14)

Note: Version bump only for package ohif-docs

[3.12.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.55...v3.12.0-beta.56) (2025-10-10)

Note: Version bump only for package ohif-docs

[3.12.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.54...v3.12.0-beta.55) (2025-10-09)

Note: Version bump only for package ohif-docs

[3.12.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.53...v3.12.0-beta.54) (2025-10-08)

Note: Version bump only for package ohif-docs

[3.12.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.52...v3.12.0-beta.53) (2025-10-07)

Note: Version bump only for package ohif-docs

[3.12.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.51...v3.12.0-beta.52) (2025-10-07)

Note: Version bump only for package ohif-docs

[3.12.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.50...v3.12.0-beta.51) (2025-10-07)

Note: Version bump only for package ohif-docs

[3.12.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.49...v3.12.0-beta.50) (2025-10-07)

Note: Version bump only for package ohif-docs

[3.12.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.48...v3.12.0-beta.49) (2025-10-07)

Note: Version bump only for package ohif-docs

[3.12.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.47...v3.12.0-beta.48) (2025-10-07)

Note: Version bump only for package ohif-docs

[3.12.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.46...v3.12.0-beta.47) (2025-10-07)

Note: Version bump only for package ohif-docs

[3.12.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.45...v3.12.0-beta.46) (2025-10-06)

Note: Version bump only for package ohif-docs

[3.12.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.44...v3.12.0-beta.45) (2025-10-06)

Note: Version bump only for package ohif-docs

[3.12.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.43...v3.12.0-beta.44) (2025-10-06)

Note: Version bump only for package ohif-docs

[3.12.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.42...v3.12.0-beta.43) (2025-10-06)

Note: Version bump only for package ohif-docs

[3.12.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.41...v3.12.0-beta.42) (2025-10-03)

Note: Version bump only for package ohif-docs

[3.12.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.40...v3.12.0-beta.41) (2025-10-03)

Note: Version bump only for package ohif-docs

[3.12.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.39...v3.12.0-beta.40) (2025-10-02)

Note: Version bump only for package ohif-docs

[3.12.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.38...v3.12.0-beta.39) (2025-10-01)

Features

  • Add inherit from basic/longitudinal modes (#5435) (9ad0d7f)

[3.12.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.37...v3.12.0-beta.38) (2025-09-30)

Note: Version bump only for package ohif-docs

[3.12.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.36...v3.12.0-beta.37) (2025-09-30)

Note: Version bump only for package ohif-docs

[3.12.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.35...v3.12.0-beta.36) (2025-09-30)

Note: Version bump only for package ohif-docs

[3.12.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.34...v3.12.0-beta.35) (2025-09-29)

Note: Version bump only for package ohif-docs

[3.12.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.33...v3.12.0-beta.34) (2025-09-29)

Note: Version bump only for package ohif-docs

[3.12.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.32...v3.12.0-beta.33) (2025-09-29)

Note: Version bump only for package ohif-docs

[3.12.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.31...v3.12.0-beta.32) (2025-09-26)

Note: Version bump only for package ohif-docs

[3.12.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.30...v3.12.0-beta.31) (2025-09-25)

Note: Version bump only for package ohif-docs

[3.12.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.29...v3.12.0-beta.30) (2025-09-25)

Note: Version bump only for package ohif-docs

[3.12.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.28...v3.12.0-beta.29) (2025-09-22)

Features

  • Segmentation: Segmentation highlight animation function selection (#5401) (69dbe27)

[3.12.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.27...v3.12.0-beta.28) (2025-09-19)

Note: Version bump only for package ohif-docs

[3.12.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.26...v3.12.0-beta.27) (2025-09-17)

Note: Version bump only for package ohif-docs

[3.12.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.25...v3.12.0-beta.26) (2025-09-17)

Note: Version bump only for package ohif-docs

[3.12.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.24...v3.12.0-beta.25) (2025-09-16)

Note: Version bump only for package ohif-docs

[3.12.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.23...v3.12.0-beta.24) (2025-09-10)

Note: Version bump only for package ohif-docs

[3.12.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.22...v3.12.0-beta.23) (2025-09-05)

Note: Version bump only for package ohif-docs

[3.12.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.21...v3.12.0-beta.22) (2025-08-29)

Note: Version bump only for package ohif-docs

[3.12.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.20...v3.12.0-beta.21) (2025-08-29)

Note: Version bump only for package ohif-docs

[3.12.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.19...v3.12.0-beta.20) (2025-08-28)

Note: Version bump only for package ohif-docs

[3.12.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.18...v3.12.0-beta.19) (2025-08-28)

Note: Version bump only for package ohif-docs

[3.12.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.17...v3.12.0-beta.18) (2025-08-28)

Note: Version bump only for package ohif-docs

[3.12.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.16...v3.12.0-beta.17) (2025-08-28)

Note: Version bump only for package ohif-docs

[3.12.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.15...v3.12.0-beta.16) (2025-08-25)

Note: Version bump only for package ohif-docs

[3.12.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.14...v3.12.0-beta.15) (2025-08-25)

Note: Version bump only for package ohif-docs

[3.12.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.13...v3.12.0-beta.14) (2025-08-25)

Note: Version bump only for package ohif-docs

[3.12.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.12...v3.12.0-beta.13) (2025-08-25)

Note: Version bump only for package ohif-docs

[3.12.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.11...v3.12.0-beta.12) (2025-08-25)

Bug Fixes

[3.12.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.10...v3.12.0-beta.11) (2025-08-25)

Note: Version bump only for package ohif-docs

[3.12.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.9...v3.12.0-beta.10) (2025-08-22)

Note: Version bump only for package ohif-docs

[3.12.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.8...v3.12.0-beta.9) (2025-08-22)

Note: Version bump only for package ohif-docs

[3.12.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.7...v3.12.0-beta.8) (2025-08-20)

Note: Version bump only for package ohif-docs

[3.12.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.6...v3.12.0-beta.7) (2025-08-15)

Note: Version bump only for package ohif-docs

[3.12.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.5...v3.12.0-beta.6) (2025-08-13)

Note: Version bump only for package ohif-docs

[3.12.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.4...v3.12.0-beta.5) (2025-08-11)

Note: Version bump only for package ohif-docs

[3.12.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.3...v3.12.0-beta.4) (2025-08-11)

Note: Version bump only for package ohif-docs

[3.12.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.2...v3.12.0-beta.3) (2025-08-11)

Note: Version bump only for package ohif-docs

[3.12.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.1...v3.12.0-beta.2) (2025-08-08)

Note: Version bump only for package ohif-docs

[3.12.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.12.0-beta.0...v3.12.0-beta.1) (2025-08-05)

Note: Version bump only for package ohif-docs

[3.12.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.116...v3.12.0-beta.0) (2025-08-05)

Note: Version bump only for package ohif-docs

[3.11.0-beta.116](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.115...v3.11.0-beta.116) (2025-08-05)

Note: Version bump only for package ohif-docs

[3.11.0-beta.115](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.114...v3.11.0-beta.115) (2025-07-31)

Features

[3.11.0-beta.114](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.113...v3.11.0-beta.114) (2025-07-30)

Note: Version bump only for package ohif-docs

[3.11.0-beta.113](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.112...v3.11.0-beta.113) (2025-07-30)

Note: Version bump only for package ohif-docs

[3.11.0-beta.112](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.111...v3.11.0-beta.112) (2025-07-28)

Note: Version bump only for package ohif-docs

[3.11.0-beta.111](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.110...v3.11.0-beta.111) (2025-07-28)

Note: Version bump only for package ohif-docs

[3.11.0-beta.110](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.109...v3.11.0-beta.110) (2025-07-28)

Note: Version bump only for package ohif-docs

[3.11.0-beta.109](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.108...v3.11.0-beta.109) (2025-07-28)

Note: Version bump only for package ohif-docs

[3.11.0-beta.108](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.107...v3.11.0-beta.108) (2025-07-25)

Note: Version bump only for package ohif-docs

[3.11.0-beta.107](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.106...v3.11.0-beta.107) (2025-07-25)

Note: Version bump only for package ohif-docs

[3.11.0-beta.106](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.105...v3.11.0-beta.106) (2025-07-24)

Note: Version bump only for package ohif-docs

[3.11.0-beta.105](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.104...v3.11.0-beta.105) (2025-07-23)

Note: Version bump only for package ohif-docs

[3.11.0-beta.104](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.103...v3.11.0-beta.104) (2025-07-23)

Note: Version bump only for package ohif-docs

[3.11.0-beta.103](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.102...v3.11.0-beta.103) (2025-07-23)

Note: Version bump only for package ohif-docs

[3.11.0-beta.102](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.101...v3.11.0-beta.102) (2025-07-23)

Note: Version bump only for package ohif-docs

[3.11.0-beta.101](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.100...v3.11.0-beta.101) (2025-07-23)

Note: Version bump only for package ohif-docs

[3.11.0-beta.100](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.99...v3.11.0-beta.100) (2025-07-23)

Note: Version bump only for package ohif-docs

[3.11.0-beta.99](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.98...v3.11.0-beta.99) (2025-07-23)

Note: Version bump only for package ohif-docs

[3.11.0-beta.98](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.97...v3.11.0-beta.98) (2025-07-23)

Bug Fixes

  • docs: Added docs for multimonitor and local linking (#5247) (83ea0ad)

[3.11.0-beta.97](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.96...v3.11.0-beta.97) (2025-07-22)

Note: Version bump only for package ohif-docs

[3.11.0-beta.96](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.95...v3.11.0-beta.96) (2025-07-22)

Note: Version bump only for package ohif-docs

[3.11.0-beta.95](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.94...v3.11.0-beta.95) (2025-07-21)

Bug Fixes

  • docs: Added entry for the showStudyList configuration setting. (#5235) (bde0eb1)

[3.11.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.93...v3.11.0-beta.94) (2025-07-21)

Note: Version bump only for package ohif-docs

[3.11.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.92...v3.11.0-beta.93) (2025-07-21)

Note: Version bump only for package ohif-docs

[3.11.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.91...v3.11.0-beta.92) (2025-07-18)

Note: Version bump only for package ohif-docs

[3.11.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.90...v3.11.0-beta.91) (2025-07-17)

Bug Fixes

  • image slices are displayed in reverse order, if we switch from common layout to 2D MPR (#5022) (6a4ca70)

[3.11.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.89...v3.11.0-beta.90) (2025-07-16)

Note: Version bump only for package ohif-docs

[3.11.0-beta.89](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.88...v3.11.0-beta.89) (2025-07-16)

Note: Version bump only for package ohif-docs

[3.11.0-beta.88](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.87...v3.11.0-beta.88) (2025-07-16)

Note: Version bump only for package ohif-docs

[3.11.0-beta.87](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.86...v3.11.0-beta.87) (2025-07-15)

Note: Version bump only for package ohif-docs

[3.11.0-beta.86](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.85...v3.11.0-beta.86) (2025-07-14)

Note: Version bump only for package ohif-docs

[3.11.0-beta.85](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.84...v3.11.0-beta.85) (2025-07-14)

Note: Version bump only for package ohif-docs

[3.11.0-beta.84](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.83...v3.11.0-beta.84) (2025-07-14)

Note: Version bump only for package ohif-docs

[3.11.0-beta.83](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.82...v3.11.0-beta.83) (2025-07-11)

Note: Version bump only for package ohif-docs

[3.11.0-beta.82](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.81...v3.11.0-beta.82) (2025-07-11)

Note: Version bump only for package ohif-docs

[3.11.0-beta.81](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.80...v3.11.0-beta.81) (2025-07-11)

Note: Version bump only for package ohif-docs

[3.11.0-beta.80](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.79...v3.11.0-beta.80) (2025-07-11)

Note: Version bump only for package ohif-docs

[3.11.0-beta.79](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.78...v3.11.0-beta.79) (2025-07-11)

Note: Version bump only for package ohif-docs

[3.11.0-beta.78](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.77...v3.11.0-beta.78) (2025-07-11)

Note: Version bump only for package ohif-docs

[3.11.0-beta.77](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.76...v3.11.0-beta.77) (2025-07-10)

Note: Version bump only for package ohif-docs

[3.11.0-beta.76](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.75...v3.11.0-beta.76) (2025-07-10)

Note: Version bump only for package ohif-docs

[3.11.0-beta.75](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.74...v3.11.0-beta.75) (2025-07-09)

Note: Version bump only for package ohif-docs

[3.11.0-beta.74](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.73...v3.11.0-beta.74) (2025-07-08)

Note: Version bump only for package ohif-docs

[3.11.0-beta.73](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.72...v3.11.0-beta.73) (2025-07-07)

Note: Version bump only for package ohif-docs

[3.11.0-beta.72](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.71...v3.11.0-beta.72) (2025-07-03)

Note: Version bump only for package ohif-docs

[3.11.0-beta.71](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.70...v3.11.0-beta.71) (2025-07-03)

Note: Version bump only for package ohif-docs

[3.11.0-beta.70](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.69...v3.11.0-beta.70) (2025-07-03)

Note: Version bump only for package ohif-docs

[3.11.0-beta.69](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.68...v3.11.0-beta.69) (2025-07-02)

Note: Version bump only for package ohif-docs

[3.11.0-beta.68](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.67...v3.11.0-beta.68) (2025-06-27)

Note: Version bump only for package ohif-docs

[3.11.0-beta.67](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.66...v3.11.0-beta.67) (2025-06-27)

Note: Version bump only for package ohif-docs

[3.11.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.65...v3.11.0-beta.66) (2025-06-27)

Note: Version bump only for package ohif-docs

[3.11.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.64...v3.11.0-beta.65) (2025-06-26)

Note: Version bump only for package ohif-docs

[3.11.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.63...v3.11.0-beta.64) (2025-06-26)

Note: Version bump only for package ohif-docs

[3.11.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.62...v3.11.0-beta.63) (2025-06-26)

Note: Version bump only for package ohif-docs

[3.11.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.61...v3.11.0-beta.62) (2025-06-25)

Note: Version bump only for package ohif-docs

[3.11.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.60...v3.11.0-beta.61) (2025-06-25)

Note: Version bump only for package ohif-docs

[3.11.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.59...v3.11.0-beta.60) (2025-06-24)

Note: Version bump only for package ohif-docs

[3.11.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.58...v3.11.0-beta.59) (2025-06-20)

Note: Version bump only for package ohif-docs

[3.11.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.57...v3.11.0-beta.58) (2025-06-18)

Note: Version bump only for package ohif-docs

[3.11.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.56...v3.11.0-beta.57) (2025-06-18)

Note: Version bump only for package ohif-docs

[3.11.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.55...v3.11.0-beta.56) (2025-06-13)

Note: Version bump only for package ohif-docs

[3.11.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.54...v3.11.0-beta.55) (2025-06-11)

Note: Version bump only for package ohif-docs

[3.11.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.53...v3.11.0-beta.54) (2025-06-11)

Note: Version bump only for package ohif-docs

[3.11.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.52...v3.11.0-beta.53) (2025-06-11)

Bug Fixes

  • data-viewportId name is illegal, renamed to data-viewportid (#5121) (75271ca)

[3.11.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.51...v3.11.0-beta.52) (2025-06-10)

Note: Version bump only for package ohif-docs

[3.11.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.50...v3.11.0-beta.51) (2025-06-09)

Note: Version bump only for package ohif-docs

[3.11.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.49...v3.11.0-beta.50) (2025-06-09)

Note: Version bump only for package ohif-docs

[3.11.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.48...v3.11.0-beta.49) (2025-06-07)

Note: Version bump only for package ohif-docs

[3.11.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.47...v3.11.0-beta.48) (2025-06-05)

Note: Version bump only for package ohif-docs

[3.11.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.46...v3.11.0-beta.47) (2025-06-02)

Note: Version bump only for package ohif-docs

[3.11.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.45...v3.11.0-beta.46) (2025-06-02)

Note: Version bump only for package ohif-docs

[3.11.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.44...v3.11.0-beta.45) (2025-05-30)

Note: Version bump only for package ohif-docs

[3.11.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.43...v3.11.0-beta.44) (2025-05-29)

Features

  • create memo when manually adding and removing annotations (#5051) (5891505)

[3.11.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.42...v3.11.0-beta.43) (2025-05-29)

Note: Version bump only for package ohif-docs

[3.11.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.41...v3.11.0-beta.42) (2025-05-28)

Note: Version bump only for package ohif-docs

[3.11.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.40...v3.11.0-beta.41) (2025-05-26)

Note: Version bump only for package ohif-docs

[3.11.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.39...v3.11.0-beta.40) (2025-05-26)

Note: Version bump only for package ohif-docs

[3.11.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.38...v3.11.0-beta.39) (2025-05-26)

Note: Version bump only for package ohif-docs

[3.11.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.37...v3.11.0-beta.38) (2025-05-24)

Note: Version bump only for package ohif-docs

[3.11.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.36...v3.11.0-beta.37) (2025-05-16)

Note: Version bump only for package ohif-docs

[3.11.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.35...v3.11.0-beta.36) (2025-05-16)

Bug Fixes

  • backward compatibility with toolbar service (#5052) (9b1b501)

[3.11.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.34...v3.11.0-beta.35) (2025-05-16)

Note: Version bump only for package ohif-docs

[3.11.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.33...v3.11.0-beta.34) (2025-05-15)

Note: Version bump only for package ohif-docs

[3.11.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.32...v3.11.0-beta.33) (2025-05-15)

Features

  • actions: simplify action corner api through the toolbarService (#5033) (7c15bb8)

[3.11.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.31...v3.11.0-beta.32) (2025-05-13)

Note: Version bump only for package ohif-docs

[3.11.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.30...v3.11.0-beta.31) (2025-05-12)

Note: Version bump only for package ohif-docs

[3.11.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.29...v3.11.0-beta.30) (2025-05-09)

Note: Version bump only for package ohif-docs

[3.11.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.28...v3.11.0-beta.29) (2025-05-08)

Features

  • app: Decouple colorbar UI from service and enable action menu programatic control (#5018) (1445e12)

[3.11.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.27...v3.11.0-beta.28) (2025-05-08)

Features

  • thumbnails: Enhance DICOM Thumbnail Rendering with different strategies (#5004) (578c393)

[3.11.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.26...v3.11.0-beta.27) (2025-05-07)

Note: Version bump only for package ohif-docs

[3.11.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.25...v3.11.0-beta.26) (2025-05-07)

Note: Version bump only for package ohif-docs

[3.11.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.24...v3.11.0-beta.25) (2025-05-06)

Note: Version bump only for package ohif-docs

[3.11.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.23...v3.11.0-beta.24) (2025-05-05)

Features

  • data overlay: add foreground background control plus orientation change in the UI and add RTDOSE support (#5007) (cd4e640)

[3.11.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.22...v3.11.0-beta.23) (2025-05-05)

Note: Version bump only for package ohif-docs

[3.11.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.21...v3.11.0-beta.22) (2025-05-02)

Note: Version bump only for package ohif-docs

[3.11.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.20...v3.11.0-beta.21) (2025-05-02)

Note: Version bump only for package ohif-docs

[3.11.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.19...v3.11.0-beta.20) (2025-05-01)

Note: Version bump only for package ohif-docs

[3.11.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.18...v3.11.0-beta.19) (2025-05-01)

Note: Version bump only for package ohif-docs

[3.11.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.17...v3.11.0-beta.18) (2025-04-30)

Note: Version bump only for package ohif-docs

[3.11.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.16...v3.11.0-beta.17) (2025-04-29)

Note: Version bump only for package ohif-docs

[3.11.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.15...v3.11.0-beta.16) (2025-04-29)

Note: Version bump only for package ohif-docs

[3.11.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.14...v3.11.0-beta.15) (2025-04-22)

Bug Fixes

  • docs: Fix SSR build errors by dynamically importing UI components and resolving other issues (#4991) (09ac43f)

[3.11.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.13...v3.11.0-beta.14) (2025-04-22)

Note: Version bump only for package ohif-docs

[3.11.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.12...v3.11.0-beta.13) (2025-04-22)

Note: Version bump only for package ohif-docs

[3.11.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.11...v3.11.0-beta.12) (2025-04-22)

Note: Version bump only for package ohif-docs

[3.11.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.10...v3.11.0-beta.11) (2025-04-18)

Note: Version bump only for package ohif-docs

[3.11.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.9...v3.11.0-beta.10) (2025-04-17)

Note: Version bump only for package ohif-docs

[3.11.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.8...v3.11.0-beta.9) (2025-04-17)

Note: Version bump only for package ohif-docs

[3.11.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.7...v3.11.0-beta.8) (2025-04-16)

Note: Version bump only for package ohif-docs

[3.11.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.6...v3.11.0-beta.7) (2025-04-16)

Note: Version bump only for package ohif-docs

[3.11.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.5...v3.11.0-beta.6) (2025-04-16)

Note: Version bump only for package ohif-docs

[3.11.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.4...v3.11.0-beta.5) (2025-04-14)

Note: Version bump only for package ohif-docs

[3.11.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.3...v3.11.0-beta.4) (2025-04-11)

Note: Version bump only for package ohif-docs

[3.11.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.2...v3.11.0-beta.3) (2025-04-11)

Note: Version bump only for package ohif-docs

[3.11.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.1...v3.11.0-beta.2) (2025-04-11)

Note: Version bump only for package ohif-docs

[3.11.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.11.0-beta.0...v3.11.0-beta.1) (2025-04-10)

Note: Version bump only for package ohif-docs

[3.11.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.159...v3.11.0-beta.0) (2025-04-10)

Note: Version bump only for package ohif-docs

[3.10.0-beta.159](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.158...v3.10.0-beta.159) (2025-04-09)

Bug Fixes

  • ui: Enhance UI Components and Update CornerstoneJS Dependencies and resizable panels (#4938) (43bc142)

[3.10.0-beta.158](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.157...v3.10.0-beta.158) (2025-04-09)

Note: Version bump only for package ohif-docs

[3.10.0-beta.157](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.156...v3.10.0-beta.157) (2025-04-09)

Note: Version bump only for package ohif-docs

[3.10.0-beta.156](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.155...v3.10.0-beta.156) (2025-04-08)

Note: Version bump only for package ohif-docs

[3.10.0-beta.155](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.154...v3.10.0-beta.155) (2025-04-08)

Note: Version bump only for package ohif-docs

[3.10.0-beta.154](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.153...v3.10.0-beta.154) (2025-04-08)

Note: Version bump only for package ohif-docs

[3.10.0-beta.153](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.152...v3.10.0-beta.153) (2025-04-08)

Note: Version bump only for package ohif-docs

[3.10.0-beta.152](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.151...v3.10.0-beta.152) (2025-04-07)

Note: Version bump only for package ohif-docs

[3.10.0-beta.151](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.150...v3.10.0-beta.151) (2025-04-07)

Note: Version bump only for package ohif-docs

[3.10.0-beta.150](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.149...v3.10.0-beta.150) (2025-04-04)

Bug Fixes

  • cine: Resolve Cine Player Faults on DisplaySet Update (#4909) (746f252)

[3.10.0-beta.149](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.148...v3.10.0-beta.149) (2025-04-04)

Features

  • image capture: Enhance SEG and RTSS Support with Dependency Updates and Bug Fixes (#4924) (fc33bd0)

[3.10.0-beta.148](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.147...v3.10.0-beta.148) (2025-04-04)

Features

  • Automate tracking prompts for a less disruptive annotation workflow (#4822) (54fded5)

[3.10.0-beta.147](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.146...v3.10.0-beta.147) (2025-04-03)

Note: Version bump only for package ohif-docs

[3.10.0-beta.146](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.145...v3.10.0-beta.146) (2025-04-02)

Note: Version bump only for package ohif-docs

[3.10.0-beta.145](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.144...v3.10.0-beta.145) (2025-04-02)

Note: Version bump only for package ohif-docs

[3.10.0-beta.144](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.143...v3.10.0-beta.144) (2025-04-01)

Note: Version bump only for package ohif-docs

[3.10.0-beta.143](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.142...v3.10.0-beta.143) (2025-04-01)

Note: Version bump only for package ohif-docs

[3.10.0-beta.142](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.141...v3.10.0-beta.142) (2025-03-31)

Note: Version bump only for package ohif-docs

[3.10.0-beta.141](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.140...v3.10.0-beta.141) (2025-03-28)

Note: Version bump only for package ohif-docs

[3.10.0-beta.140](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.139...v3.10.0-beta.140) (2025-03-27)

Bug Fixes

[3.10.0-beta.139](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.138...v3.10.0-beta.139) (2025-03-27)

Note: Version bump only for package ohif-docs

[3.10.0-beta.138](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.137...v3.10.0-beta.138) (2025-03-26)

Bug Fixes

  • remove duplicated deleteMeasurements code (#4895) (9bde644)

[3.10.0-beta.137](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.136...v3.10.0-beta.137) (2025-03-26)

Note: Version bump only for package ohif-docs

[3.10.0-beta.136](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.135...v3.10.0-beta.136) (2025-03-25)

Note: Version bump only for package ohif-docs

[3.10.0-beta.135](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.134...v3.10.0-beta.135) (2025-03-25)

Note: Version bump only for package ohif-docs

[3.10.0-beta.134](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.133...v3.10.0-beta.134) (2025-03-20)

Note: Version bump only for package ohif-docs

[3.10.0-beta.133](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.132...v3.10.0-beta.133) (2025-03-20)

Features

  • add customization to PanelStudyBrowser dbl click callback (#4871) (01c3726)

[3.10.0-beta.132](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.131...v3.10.0-beta.132) (2025-03-20)

Features

  • Group findings table values with custom components/grouping functions (#4712) (df8efba)

[3.10.0-beta.131](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.130...v3.10.0-beta.131) (2025-03-19)

Note: Version bump only for package ohif-docs

[3.10.0-beta.130](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.129...v3.10.0-beta.130) (2025-03-19)

Note: Version bump only for package ohif-docs

[3.10.0-beta.129](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.128...v3.10.0-beta.129) (2025-03-18)

Note: Version bump only for package ohif-docs

[3.10.0-beta.128](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.127...v3.10.0-beta.128) (2025-03-18)

Note: Version bump only for package ohif-docs

[3.10.0-beta.127](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.126...v3.10.0-beta.127) (2025-03-18)

Note: Version bump only for package ohif-docs

[3.10.0-beta.126](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.125...v3.10.0-beta.126) (2025-03-18)

Features

  • segmentation: segment statistics, labelmap interpolation and segment bidirectional (#4865) (ec79b55)

[3.10.0-beta.125](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.124...v3.10.0-beta.125) (2025-03-17)

Note: Version bump only for package ohif-docs

[3.10.0-beta.124](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.123...v3.10.0-beta.124) (2025-03-17)

Note: Version bump only for package ohif-docs

[3.10.0-beta.123](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.122...v3.10.0-beta.123) (2025-03-17)

Note: Version bump only for package ohif-docs

[3.10.0-beta.122](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.121...v3.10.0-beta.122) (2025-03-17)

Note: Version bump only for package ohif-docs

[3.10.0-beta.121](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.120...v3.10.0-beta.121) (2025-03-11)

Note: Version bump only for package ohif-docs

[3.10.0-beta.120](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.119...v3.10.0-beta.120) (2025-03-11)

Note: Version bump only for package ohif-docs

[3.10.0-beta.119](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.118...v3.10.0-beta.119) (2025-03-10)

Note: Version bump only for package ohif-docs

[3.10.0-beta.118](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.117...v3.10.0-beta.118) (2025-03-07)

Note: Version bump only for package ohif-docs

[3.10.0-beta.117](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.116...v3.10.0-beta.117) (2025-03-07)

Features

  • toolbox: Refactor Toolbar and Toolbox to enable sections (#4825) (cc5cdfb)

[3.10.0-beta.116](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.115...v3.10.0-beta.116) (2025-03-06)

Note: Version bump only for package ohif-docs

[3.10.0-beta.115](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.114...v3.10.0-beta.115) (2025-02-28)

Note: Version bump only for package ohif-docs

[3.10.0-beta.114](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.113...v3.10.0-beta.114) (2025-02-28)

Note: Version bump only for package ohif-docs

[3.10.0-beta.113](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.112...v3.10.0-beta.113) (2025-02-28)

Note: Version bump only for package ohif-docs

[3.10.0-beta.112](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.111...v3.10.0-beta.112) (2025-02-28)

Features

  • separate checks for addWindowLevelActionMenu and addSegmentationOverlay (#4813) (7f0cc0f)

[3.10.0-beta.111](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.110...v3.10.0-beta.111) (2025-02-26)

Note: Version bump only for package ohif-docs

[3.10.0-beta.110](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.109...v3.10.0-beta.110) (2025-02-26)

Note: Version bump only for package ohif-docs

[3.10.0-beta.109](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.108...v3.10.0-beta.109) (2025-02-25)

Note: Version bump only for package ohif-docs

[3.10.0-beta.108](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.107...v3.10.0-beta.108) (2025-02-25)

Note: Version bump only for package ohif-docs

[3.10.0-beta.107](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.106...v3.10.0-beta.107) (2025-02-25)

Note: Version bump only for package ohif-docs

[3.10.0-beta.106](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.105...v3.10.0-beta.106) (2025-02-25)

Features

  • hotkeys: Migrate hotkeys to customization service and fix issues with overrides (#4777) (3e6913b)

[3.10.0-beta.105](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.104...v3.10.0-beta.105) (2025-02-25)

Note: Version bump only for package ohif-docs

[3.10.0-beta.104](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.103...v3.10.0-beta.104) (2025-02-25)

Note: Version bump only for package ohif-docs

[3.10.0-beta.103](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.102...v3.10.0-beta.103) (2025-02-23)

Note: Version bump only for package ohif-docs

[3.10.0-beta.102](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.101...v3.10.0-beta.102) (2025-02-20)

Note: Version bump only for package ohif-docs

[3.10.0-beta.101](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.100...v3.10.0-beta.101) (2025-02-20)

Note: Version bump only for package ohif-docs

[3.10.0-beta.100](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.99...v3.10.0-beta.100) (2025-02-19)

Note: Version bump only for package ohif-docs

[3.10.0-beta.99](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.98...v3.10.0-beta.99) (2025-02-18)

Note: Version bump only for package ohif-docs

[3.10.0-beta.98](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.97...v3.10.0-beta.98) (2025-02-18)

Note: Version bump only for package ohif-docs

[3.10.0-beta.97](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.96...v3.10.0-beta.97) (2025-02-18)

Note: Version bump only for package ohif-docs

[3.10.0-beta.96](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.95...v3.10.0-beta.96) (2025-02-18)

Note: Version bump only for package ohif-docs

[3.10.0-beta.95](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.94...v3.10.0-beta.95) (2025-02-13)

Note: Version bump only for package ohif-docs

[3.10.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.93...v3.10.0-beta.94) (2025-02-11)

Note: Version bump only for package ohif-docs

[3.10.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.92...v3.10.0-beta.93) (2025-02-04)

Note: Version bump only for package ohif-docs

[3.10.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.91...v3.10.0-beta.92) (2025-02-04)

Bug Fixes

  • core: Address 3D reconstruction and Android compatibility issues and clean up 4D data mode (#4762) (149d6d0)

[3.10.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.90...v3.10.0-beta.91) (2025-02-04)

Note: Version bump only for package ohif-docs

[3.10.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.89...v3.10.0-beta.90) (2025-02-04)

Features

  • ui: Add support for Custom Modal component in Modal Service (#4752) (2c183aa)

[3.10.0-beta.89](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.88...v3.10.0-beta.89) (2025-02-04)

Features

  • ui: customization option for viewport notification (#4638) (8acbd76)

[3.10.0-beta.88](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.87...v3.10.0-beta.88) (2025-02-04)

Note: Version bump only for package ohif-docs

[3.10.0-beta.87](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.86...v3.10.0-beta.87) (2025-02-03)

Note: Version bump only for package ohif-docs

[3.10.0-beta.86](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.85...v3.10.0-beta.86) (2025-02-03)

Note: Version bump only for package ohif-docs

[3.10.0-beta.85](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.84...v3.10.0-beta.85) (2025-02-03)

Features

  • Add customization support for more UI components (#4634) (f15eb44)

[3.10.0-beta.84](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.83...v3.10.0-beta.84) (2025-01-31)

Note: Version bump only for package ohif-docs

[3.10.0-beta.83](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.82...v3.10.0-beta.83) (2025-01-31)

Note: Version bump only for package ohif-docs

[3.10.0-beta.82](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.81...v3.10.0-beta.82) (2025-01-31)

Note: Version bump only for package ohif-docs

[3.10.0-beta.81](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.80...v3.10.0-beta.81) (2025-01-29)

Note: Version bump only for package ohif-docs

[3.10.0-beta.80](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.79...v3.10.0-beta.80) (2025-01-29)

Features

  • customization: enable custom onDropHandler for viewportGrid (#4641) (054b262)

[3.10.0-beta.79](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.78...v3.10.0-beta.79) (2025-01-28)

Bug Fixes

  • dependencies: Update dcmjs library and improve documentation links (#4741) (d554f02)

[3.10.0-beta.78](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.77...v3.10.0-beta.78) (2025-01-28)

Note: Version bump only for package ohif-docs

[3.10.0-beta.77](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.76...v3.10.0-beta.77) (2025-01-28)

Note: Version bump only for package ohif-docs

[3.10.0-beta.76](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.75...v3.10.0-beta.76) (2025-01-27)

Note: Version bump only for package ohif-docs

[3.10.0-beta.75](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.74...v3.10.0-beta.75) (2025-01-27)

Features

  • static-wado: add support for case-insensitive searching (#4603) (ac6e674)

[3.10.0-beta.74](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.73...v3.10.0-beta.74) (2025-01-27)

Note: Version bump only for package ohif-docs

[3.10.0-beta.73](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.72...v3.10.0-beta.73) (2025-01-24)

Bug Fixes

[3.10.0-beta.72](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.71...v3.10.0-beta.72) (2025-01-24)

Note: Version bump only for package ohif-docs

[3.10.0-beta.71](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.70...v3.10.0-beta.71) (2025-01-23)

Features

  • customization: new customization service api (#4688) (55ad8ef)

[3.10.0-beta.70](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.69...v3.10.0-beta.70) (2025-01-23)

Note: Version bump only for package ohif-docs

[3.10.0-beta.69](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.68...v3.10.0-beta.69) (2025-01-22)

Bug Fixes

  • seg: sphere scissor on stack and cpu rendering reset properties was broken (#4721) (f00d182)

[3.10.0-beta.68](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.67...v3.10.0-beta.68) (2025-01-21)

Note: Version bump only for package ohif-docs

[3.10.0-beta.67](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.66...v3.10.0-beta.67) (2025-01-21)

Bug Fixes

  • ui: Update dependencies and add missing icons (#4699) (cf97fa9)

[3.10.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.65...v3.10.0-beta.66) (2025-01-21)

Note: Version bump only for package ohif-docs

[3.10.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.64...v3.10.0-beta.65) (2025-01-20)

Note: Version bump only for package ohif-docs

[3.10.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.63...v3.10.0-beta.64) (2025-01-20)

Note: Version bump only for package ohif-docs

[3.10.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.62...v3.10.0-beta.63) (2025-01-17)

Note: Version bump only for package ohif-docs

[3.10.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.61...v3.10.0-beta.62) (2025-01-16)

Note: Version bump only for package ohif-docs

[3.10.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.60...v3.10.0-beta.61) (2025-01-16)

Note: Version bump only for package ohif-docs

[3.10.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.59...v3.10.0-beta.60) (2025-01-15)

Note: Version bump only for package ohif-docs

[3.10.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.58...v3.10.0-beta.59) (2025-01-14)

Note: Version bump only for package ohif-docs

[3.10.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.57...v3.10.0-beta.58) (2025-01-13)

Features

  • multimonitor: Add simple multi-monitor support to open another study(#4178) (07c628e)

[3.10.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.56...v3.10.0-beta.57) (2025-01-13)

Note: Version bump only for package ohif-docs

[3.10.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.55...v3.10.0-beta.56) (2025-01-13)

Note: Version bump only for package ohif-docs

[3.10.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.54...v3.10.0-beta.55) (2025-01-10)

Features

[3.10.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.53...v3.10.0-beta.54) (2025-01-10)

Note: Version bump only for package ohif-docs

[3.10.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.52...v3.10.0-beta.53) (2025-01-10)

Note: Version bump only for package ohif-docs

[3.10.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.51...v3.10.0-beta.52) (2025-01-10)

Note: Version bump only for package ohif-docs

[3.10.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.50...v3.10.0-beta.51) (2025-01-10)

Note: Version bump only for package ohif-docs

[3.10.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.49...v3.10.0-beta.50) (2025-01-10)

Note: Version bump only for package ohif-docs

[3.10.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.48...v3.10.0-beta.49) (2025-01-09)

Note: Version bump only for package ohif-docs

[3.10.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.47...v3.10.0-beta.48) (2025-01-09)

Note: Version bump only for package ohif-docs

[3.10.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.46...v3.10.0-beta.47) (2025-01-09)

Note: Version bump only for package ohif-docs

[3.10.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.45...v3.10.0-beta.46) (2025-01-08)

Note: Version bump only for package ohif-docs

[3.10.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.44...v3.10.0-beta.45) (2025-01-08)

Note: Version bump only for package ohif-docs

[3.10.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.43...v3.10.0-beta.44) (2025-01-08)

Note: Version bump only for package ohif-docs

[3.10.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.42...v3.10.0-beta.43) (2025-01-08)

Note: Version bump only for package ohif-docs

[3.10.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.41...v3.10.0-beta.42) (2025-01-08)

Note: Version bump only for package ohif-docs

[3.10.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.40...v3.10.0-beta.41) (2025-01-08)

Note: Version bump only for package ohif-docs

[3.10.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.39...v3.10.0-beta.40) (2025-01-08)

Note: Version bump only for package ohif-docs

[3.10.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.38...v3.10.0-beta.39) (2025-01-08)

Note: Version bump only for package ohif-docs

[3.10.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.37...v3.10.0-beta.38) (2025-01-07)

Note: Version bump only for package ohif-docs

[3.10.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.36...v3.10.0-beta.37) (2025-01-06)

Note: Version bump only for package ohif-docs

[3.10.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.35...v3.10.0-beta.36) (2025-01-03)

Note: Version bump only for package ohif-docs

[3.10.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.34...v3.10.0-beta.35) (2025-01-03)

Note: Version bump only for package ohif-docs

[3.10.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.33...v3.10.0-beta.34) (2025-01-02)

Bug Fixes

  • Docker build time was very slow on a tiny change (#4559) (7e43b2f)

[3.10.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.32...v3.10.0-beta.33) (2024-12-20)

Note: Version bump only for package ohif-docs

[3.10.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.31...v3.10.0-beta.32) (2024-12-20)

Note: Version bump only for package ohif-docs

[3.10.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.30...v3.10.0-beta.31) (2024-12-20)

Note: Version bump only for package ohif-docs

[3.10.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.29...v3.10.0-beta.30) (2024-12-18)

Note: Version bump only for package ohif-docs

[3.10.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.28...v3.10.0-beta.29) (2024-12-18)

Note: Version bump only for package ohif-docs

[3.10.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.27...v3.10.0-beta.28) (2024-12-18)

Note: Version bump only for package ohif-docs

[3.10.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.26...v3.10.0-beta.27) (2024-12-18)

Note: Version bump only for package ohif-docs

[3.10.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.25...v3.10.0-beta.26) (2024-12-18)

Note: Version bump only for package ohif-docs

[3.10.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.24...v3.10.0-beta.25) (2024-12-17)

Bug Fixes

  • Documentation and default enabled for bulkdata load (#4607) (d0ccdbd)

[3.10.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.23...v3.10.0-beta.24) (2024-12-17)

Features

[3.10.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.22...v3.10.0-beta.23) (2024-12-17)

Note: Version bump only for package ohif-docs

[3.10.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.21...v3.10.0-beta.22) (2024-12-13)

Note: Version bump only for package ohif-docs

[3.10.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.20...v3.10.0-beta.21) (2024-12-11)

Features

[3.10.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.19...v3.10.0-beta.20) (2024-12-11)

Note: Version bump only for package ohif-docs

[3.10.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.18...v3.10.0-beta.19) (2024-12-11)

Note: Version bump only for package ohif-docs

[3.10.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.17...v3.10.0-beta.18) (2024-12-06)

Note: Version bump only for package ohif-docs

[3.10.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.16...v3.10.0-beta.17) (2024-12-06)

Note: Version bump only for package ohif-docs

[3.10.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.15...v3.10.0-beta.16) (2024-12-05)

Note: Version bump only for package ohif-docs

[3.10.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.14...v3.10.0-beta.15) (2024-12-05)

Note: Version bump only for package ohif-docs

[3.10.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.13...v3.10.0-beta.14) (2024-12-03)

Note: Version bump only for package ohif-docs

[3.10.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.12...v3.10.0-beta.13) (2024-12-02)

Note: Version bump only for package ohif-docs

[3.10.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.11...v3.10.0-beta.12) (2024-11-29)

Note: Version bump only for package ohif-docs

[3.10.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.10...v3.10.0-beta.11) (2024-11-28)

Bug Fixes

  • multiframe: metadata handling of NM studies and loading order (#4554) (7624ccb)

[3.10.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.9...v3.10.0-beta.10) (2024-11-28)

Note: Version bump only for package ohif-docs

[3.10.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.8...v3.10.0-beta.9) (2024-11-22)

Note: Version bump only for package ohif-docs

[3.10.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.7...v3.10.0-beta.8) (2024-11-22)

Note: Version bump only for package ohif-docs

[3.10.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.6...v3.10.0-beta.7) (2024-11-22)

Bug Fixes

  • Make the commands ordering the registration order of hte mode (#4492) (edfaf72)

[3.10.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.5...v3.10.0-beta.6) (2024-11-22)

Note: Version bump only for package ohif-docs

[3.10.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.4...v3.10.0-beta.5) (2024-11-15)

Note: Version bump only for package ohif-docs

[3.10.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.3...v3.10.0-beta.4) (2024-11-15)

Note: Version bump only for package ohif-docs

[3.10.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.2...v3.10.0-beta.3) (2024-11-14)

Note: Version bump only for package ohif-docs

[3.10.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.1...v3.10.0-beta.2) (2024-11-13)

Note: Version bump only for package ohif-docs

[3.10.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.10.0-beta.0...v3.10.0-beta.1) (2024-11-12)

Note: Version bump only for package ohif-docs

[3.10.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.111...v3.10.0-beta.0) (2024-11-12)

Note: Version bump only for package ohif-docs

[3.9.0-beta.111](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.110...v3.9.0-beta.111) (2024-11-12)

Bug Fixes

  • Have an addIcon that adds to both ui and ui-next (#4490) (4a12523)
  • Measurement Tracking: Various UI and functionality improvements (#4481) (62b2748)

[3.9.0-beta.110](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.109...v3.9.0-beta.110) (2024-11-11)

Bug Fixes

  • bugs: Update dependencies and enhance UI components (#4478) (05d41c5)

[3.9.0-beta.109](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.108...v3.9.0-beta.109) (2024-11-08)

Note: Version bump only for package ohif-docs

[3.9.0-beta.108](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.107...v3.9.0-beta.108) (2024-11-07)

Bug Fixes

  • tmtv: fix toggle one up weird behaviours (#4473) (aa2b649)

[3.9.0-beta.107](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.106...v3.9.0-beta.107) (2024-11-06)

Note: Version bump only for package ohif-docs

[3.9.0-beta.106](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.105...v3.9.0-beta.106) (2024-11-06)

Note: Version bump only for package ohif-docs

[3.9.0-beta.105](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.104...v3.9.0-beta.105) (2024-11-05)

Note: Version bump only for package ohif-docs

[3.9.0-beta.104](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.103...v3.9.0-beta.104) (2024-10-30)

Note: Version bump only for package ohif-docs

[3.9.0-beta.103](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.102...v3.9.0-beta.103) (2024-10-29)

Note: Version bump only for package ohif-docs

[3.9.0-beta.102](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.101...v3.9.0-beta.102) (2024-10-29)

Note: Version bump only for package ohif-docs

[3.9.0-beta.101](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.100...v3.9.0-beta.101) (2024-10-18)

Note: Version bump only for package ohif-docs

[3.9.0-beta.100](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.99...v3.9.0-beta.100) (2024-10-17)

Note: Version bump only for package ohif-docs

[3.9.0-beta.99](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.98...v3.9.0-beta.99) (2024-10-17)

Note: Version bump only for package ohif-docs

[3.9.0-beta.98](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.97...v3.9.0-beta.98) (2024-10-15)

Note: Version bump only for package ohif-docs

[3.9.0-beta.97](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.96...v3.9.0-beta.97) (2024-10-11)

Note: Version bump only for package ohif-docs

[3.9.0-beta.96](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.95...v3.9.0-beta.96) (2024-10-10)

Note: Version bump only for package ohif-docs

[3.9.0-beta.95](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.94...v3.9.0-beta.95) (2024-10-08)

Note: Version bump only for package ohif-docs

[3.9.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.93...v3.9.0-beta.94) (2024-10-04)

Features

  • tours: freeze versions and add licensings doc (#4407) (60a8d51)

[3.9.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.92...v3.9.0-beta.93) (2024-10-04)

Note: Version bump only for package ohif-docs

[3.9.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.91...v3.9.0-beta.92) (2024-10-01)

Note: Version bump only for package ohif-docs

[3.9.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.90...v3.9.0-beta.91) (2024-10-01)

Note: Version bump only for package ohif-docs

[3.9.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.89...v3.9.0-beta.90) (2024-09-30)

Note: Version bump only for package ohif-docs

[3.9.0-beta.89](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.88...v3.9.0-beta.89) (2024-09-27)

Note: Version bump only for package ohif-docs

[3.9.0-beta.88](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.87...v3.9.0-beta.88) (2024-09-24)

Note: Version bump only for package ohif-docs

[3.9.0-beta.87](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.86...v3.9.0-beta.87) (2024-09-19)

Note: Version bump only for package ohif-docs

[3.9.0-beta.86](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.85...v3.9.0-beta.86) (2024-09-19)

Note: Version bump only for package ohif-docs

[3.9.0-beta.85](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.84...v3.9.0-beta.85) (2024-09-17)

Note: Version bump only for package ohif-docs

[3.9.0-beta.84](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.83...v3.9.0-beta.84) (2024-09-12)

Note: Version bump only for package ohif-docs

[3.9.0-beta.83](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.82...v3.9.0-beta.83) (2024-09-11)

Note: Version bump only for package ohif-docs

[3.9.0-beta.82](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.81...v3.9.0-beta.82) (2024-09-05)

Note: Version bump only for package ohif-docs

[3.9.0-beta.81](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.80...v3.9.0-beta.81) (2024-08-27)

Note: Version bump only for package ohif-docs

[3.9.0-beta.80](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.79...v3.9.0-beta.80) (2024-08-16)

Note: Version bump only for package ohif-docs

[3.9.0-beta.79](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.78...v3.9.0-beta.79) (2024-08-16)

Note: Version bump only for package ohif-docs

[3.9.0-beta.78](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.77...v3.9.0-beta.78) (2024-08-15)

Features

  • Add CS3D WSI and Video Viewports and add annotation navigation for MPR (#4182) (7599ec9)

[3.9.0-beta.77](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.76...v3.9.0-beta.77) (2024-08-15)

Note: Version bump only for package ohif-docs

[3.9.0-beta.76](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.75...v3.9.0-beta.76) (2024-08-08)

Note: Version bump only for package ohif-docs

[3.9.0-beta.75](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.74...v3.9.0-beta.75) (2024-08-07)

Note: Version bump only for package ohif-docs

[3.9.0-beta.74](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.73...v3.9.0-beta.74) (2024-08-06)

Note: Version bump only for package ohif-docs

[3.9.0-beta.73](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.72...v3.9.0-beta.73) (2024-08-02)

Note: Version bump only for package ohif-docs

[3.9.0-beta.72](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.71...v3.9.0-beta.72) (2024-07-31)

Note: Version bump only for package ohif-docs

[3.9.0-beta.71](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.70...v3.9.0-beta.71) (2024-07-30)

Note: Version bump only for package ohif-docs

[3.9.0-beta.70](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.69...v3.9.0-beta.70) (2024-07-30)

Note: Version bump only for package ohif-docs

[3.9.0-beta.69](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.68...v3.9.0-beta.69) (2024-07-27)

Note: Version bump only for package ohif-docs

[3.9.0-beta.68](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.67...v3.9.0-beta.68) (2024-07-26)

Note: Version bump only for package ohif-docs

[3.9.0-beta.67](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.66...v3.9.0-beta.67) (2024-07-26)

Note: Version bump only for package ohif-docs

[3.9.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.65...v3.9.0-beta.66) (2024-07-24)

Note: Version bump only for package ohif-docs

[3.9.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.64...v3.9.0-beta.65) (2024-07-23)

Note: Version bump only for package ohif-docs

[3.9.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.63...v3.9.0-beta.64) (2024-07-19)

Note: Version bump only for package ohif-docs

[3.9.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.62...v3.9.0-beta.63) (2024-07-10)

Note: Version bump only for package ohif-docs

[3.9.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.61...v3.9.0-beta.62) (2024-07-09)

Note: Version bump only for package ohif-docs

[3.9.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.60...v3.9.0-beta.61) (2024-07-09)

Features

  • auth: Add Authorization Code Flow and new Keycloak recipes with new video tutorials (#4234) (aefa6d9)

[3.9.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.59...v3.9.0-beta.60) (2024-07-09)

Note: Version bump only for package ohif-docs

[3.9.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.58...v3.9.0-beta.59) (2024-07-05)

Bug Fixes

  • webpack import bugs showing warnings on import (#4265) (24c511f)

Features

  • Add interleaved HTJ2K and volume progressive loading (#4276) (a2084f3)

[3.9.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.57...v3.9.0-beta.58) (2024-07-04)

Note: Version bump only for package ohif-docs

[3.9.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.56...v3.9.0-beta.57) (2024-07-02)

Note: Version bump only for package ohif-docs

[3.9.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.55...v3.9.0-beta.56) (2024-07-02)

Note: Version bump only for package ohif-docs

[3.9.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.54...v3.9.0-beta.55) (2024-06-28)

Note: Version bump only for package ohif-docs

[3.9.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.53...v3.9.0-beta.54) (2024-06-28)

Features

[3.9.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.52...v3.9.0-beta.53) (2024-06-28)

Note: Version bump only for package ohif-docs

[3.9.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.51...v3.9.0-beta.52) (2024-06-27)

Note: Version bump only for package ohif-docs

[3.9.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.50...v3.9.0-beta.51) (2024-06-27)

Bug Fixes

  • cli: Fix the cli utilities which require full paths (d09f8b5), closes #4267

[3.9.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.49...v3.9.0-beta.50) (2024-06-26)

Note: Version bump only for package ohif-docs

[3.9.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.48...v3.9.0-beta.49) (2024-06-26)

Note: Version bump only for package ohif-docs

[3.9.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.47...v3.9.0-beta.48) (2024-06-25)

Note: Version bump only for package ohif-docs

[3.9.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.46...v3.9.0-beta.47) (2024-06-21)

Bug Fixes

  • Allow the mode setup/creation to be async, and provide a few more values to extension/app config/mode setup. (#4016) (88575c6)
  • CustomViewportOverlay: pass accurate data to Custom Viewport Functions (#4224) (aef00e9)

Features

  • customization service append and customize functionality should run once (#4238) (e462fd3)
  • sort: custom series sort in study panel (#4214) (a433d40)

[3.9.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.45...v3.9.0-beta.46) (2024-06-18)

Note: Version bump only for package ohif-docs

[3.9.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.44...v3.9.0-beta.45) (2024-06-18)

Note: Version bump only for package ohif-docs

[3.9.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.43...v3.9.0-beta.44) (2024-06-17)

Bug Fixes

  • cli: version txt had a new line which it should not (#4233) (097ef76)

[3.9.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.42...v3.9.0-beta.43) (2024-06-12)

Note: Version bump only for package ohif-docs

[3.9.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.41...v3.9.0-beta.42) (2024-06-12)

Note: Version bump only for package ohif-docs

[3.9.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.40...v3.9.0-beta.41) (2024-06-12)

Note: Version bump only for package ohif-docs

[3.9.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.39...v3.9.0-beta.40) (2024-06-12)

Note: Version bump only for package ohif-docs

[3.9.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.38...v3.9.0-beta.39) (2024-06-08)

Note: Version bump only for package ohif-docs

[3.9.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.37...v3.9.0-beta.38) (2024-06-07)

Note: Version bump only for package ohif-docs

[3.9.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.36...v3.9.0-beta.37) (2024-06-05)

Note: Version bump only for package ohif-docs

[3.9.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.35...v3.9.0-beta.36) (2024-06-05)

Note: Version bump only for package ohif-docs

[3.9.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.34...v3.9.0-beta.35) (2024-06-05)

Note: Version bump only for package ohif-docs

[3.9.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.33...v3.9.0-beta.34) (2024-06-05)

Note: Version bump only for package ohif-docs

[3.9.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.32...v3.9.0-beta.33) (2024-06-05)

Note: Version bump only for package ohif-docs

[3.9.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.31...v3.9.0-beta.32) (2024-05-31)

Note: Version bump only for package ohif-docs

[3.9.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.30...v3.9.0-beta.31) (2024-05-30)

Note: Version bump only for package ohif-docs

[3.9.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.29...v3.9.0-beta.30) (2024-05-30)

Note: Version bump only for package ohif-docs

[3.9.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.28...v3.9.0-beta.29) (2024-05-30)

Note: Version bump only for package ohif-docs

[3.9.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.27...v3.9.0-beta.28) (2024-05-30)

Note: Version bump only for package ohif-docs

[3.9.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.26...v3.9.0-beta.27) (2024-05-29)

Note: Version bump only for package ohif-docs

[3.9.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.25...v3.9.0-beta.26) (2024-05-29)

Features

  • hp: Add displayArea option for Hanging protocols and example with Mamo(#3808) (18ac08e)

[3.9.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.24...v3.9.0-beta.25) (2024-05-29)

Note: Version bump only for package ohif-docs

[3.9.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.23...v3.9.0-beta.24) (2024-05-29)

Note: Version bump only for package ohif-docs

[3.9.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.22...v3.9.0-beta.23) (2024-05-28)

Note: Version bump only for package ohif-docs

[3.9.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.21...v3.9.0-beta.22) (2024-05-27)

Features

  • ui: move to React 18 and base for using shadcn/ui (#4174) (70f2c79)

[3.9.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.20...v3.9.0-beta.21) (2024-05-24)

Note: Version bump only for package ohif-docs

[3.9.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.19...v3.9.0-beta.20) (2024-05-24)

Note: Version bump only for package ohif-docs

[3.9.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.18...v3.9.0-beta.19) (2024-05-24)

Note: Version bump only for package ohif-docs

[3.9.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.17...v3.9.0-beta.18) (2024-05-24)

Note: Version bump only for package ohif-docs

[3.9.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.16...v3.9.0-beta.17) (2024-05-23)

Note: Version bump only for package ohif-docs

[3.9.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.15...v3.9.0-beta.16) (2024-05-23)

Note: Version bump only for package ohif-docs

[3.9.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.14...v3.9.0-beta.15) (2024-05-22)

Note: Version bump only for package ohif-docs

[3.9.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.13...v3.9.0-beta.14) (2024-05-21)

Note: Version bump only for package ohif-docs

[3.9.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.12...v3.9.0-beta.13) (2024-05-21)

Note: Version bump only for package ohif-docs

[3.9.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.11...v3.9.0-beta.12) (2024-05-21)

Note: Version bump only for package ohif-docs

[3.9.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.10...v3.9.0-beta.11) (2024-05-21)

Features

[3.9.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.9...v3.9.0-beta.10) (2024-05-21)

Note: Version bump only for package ohif-docs

[3.9.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.8...v3.9.0-beta.9) (2024-05-17)

Note: Version bump only for package ohif-docs

[3.9.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.7...v3.9.0-beta.8) (2024-05-16)

Note: Version bump only for package ohif-docs

[3.9.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.6...v3.9.0-beta.7) (2024-05-15)

Note: Version bump only for package ohif-docs

[3.9.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.5...v3.9.0-beta.6) (2024-05-15)

Note: Version bump only for package ohif-docs

[3.9.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.4...v3.9.0-beta.5) (2024-05-14)

Note: Version bump only for package ohif-docs

[3.9.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.3...v3.9.0-beta.4) (2024-05-14)

Note: Version bump only for package ohif-docs

[3.9.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.2...v3.9.0-beta.3) (2024-05-08)

Features

  • typings: Enhance typing support with withAppTypes and custom services throughout OHIF (#4090) (374065b)

[3.9.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.1...v3.9.0-beta.2) (2024-05-06)

Bug Fixes

  • bugs: enhancements and bugs in several areas (#4086) (730f434)

[3.9.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.9.0-beta.0...v3.9.0-beta.1) (2024-05-06)

Note: Version bump only for package ohif-docs

[3.9.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.94...v3.9.0-beta.0) (2024-04-29)

Note: Version bump only for package ohif-docs

[3.8.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.93...v3.8.0-beta.94) (2024-04-29)

Note: Version bump only for package ohif-docs

[3.8.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.92...v3.8.0-beta.93) (2024-04-29)

Bug Fixes

  • toolbox: Preserve user-specified tool state and streamline command execution (#4063) (f1a736d)

[3.8.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.91...v3.8.0-beta.92) (2024-04-28)

Note: Version bump only for package ohif-docs

[3.8.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.90...v3.8.0-beta.91) (2024-04-25)

Note: Version bump only for package ohif-docs

[3.8.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.89...v3.8.0-beta.90) (2024-04-22)

Note: Version bump only for package ohif-docs

[3.8.0-beta.89](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.88...v3.8.0-beta.89) (2024-04-22)

Note: Version bump only for package ohif-docs

[3.8.0-beta.88](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.87...v3.8.0-beta.88) (2024-04-22)

Note: Version bump only for package ohif-docs

[3.8.0-beta.87](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.86...v3.8.0-beta.87) (2024-04-19)

Features

  • tmtv-mode: Add Brush tools and move SUV peak calculation to web worker (#4053) (8192e34)

[3.8.0-beta.86](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.85...v3.8.0-beta.86) (2024-04-19)

Bug Fixes

  • layouts: and fix thumbnail in touch and update migration guide for 3.8 release (#4052) (d250d04)

[3.8.0-beta.85](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.84...v3.8.0-beta.85) (2024-04-18)

Note: Version bump only for package ohif-docs

[3.8.0-beta.84](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.83...v3.8.0-beta.84) (2024-04-18)

Bug Fixes

  • bugs: and replace seriesInstanceUID and seriesInstanceUIDs URL with seriesInstanceUIDs (#4049) (da7c1a5)

[3.8.0-beta.83](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.82...v3.8.0-beta.83) (2024-04-18)

Note: Version bump only for package ohif-docs

[3.8.0-beta.82](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.81...v3.8.0-beta.82) (2024-04-17)

Note: Version bump only for package ohif-docs

[3.8.0-beta.81](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.80...v3.8.0-beta.81) (2024-04-16)

Bug Fixes

  • viewport: Reset viewport state and fix CINE looping, thumbnail resolution, and dynamic tool settings (#4037) (f99a0bf)

[3.8.0-beta.80](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.79...v3.8.0-beta.80) (2024-04-16)

Bug Fixes

[3.8.0-beta.79](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.78...v3.8.0-beta.79) (2024-04-10)

Note: Version bump only for package ohif-docs

[3.8.0-beta.78](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.77...v3.8.0-beta.78) (2024-04-10)

Note: Version bump only for package ohif-docs

[3.8.0-beta.77](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.76...v3.8.0-beta.77) (2024-04-10)

Note: Version bump only for package ohif-docs

[3.8.0-beta.76](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.75...v3.8.0-beta.76) (2024-04-10)

Note: Version bump only for package ohif-docs

[3.8.0-beta.75](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.74...v3.8.0-beta.75) (2024-04-10)

Note: Version bump only for package ohif-docs

[3.8.0-beta.74](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.73...v3.8.0-beta.74) (2024-04-10)

Features

  • 4D: Add 4D dynamic volume rendering and new pre-clinical 4d pt/ct mode (#3664) (d57e8bc)

[3.8.0-beta.73](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.72...v3.8.0-beta.73) (2024-04-08)

Note: Version bump only for package ohif-docs

[3.8.0-beta.72](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.71...v3.8.0-beta.72) (2024-04-05)

Note: Version bump only for package ohif-docs

[3.8.0-beta.71](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.70...v3.8.0-beta.71) (2024-04-05)

Note: Version bump only for package ohif-docs

[3.8.0-beta.70](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.69...v3.8.0-beta.70) (2024-04-05)

Features

  • measurement: Add support measurement label autocompletion (#3855) (56b1eae)

[3.8.0-beta.69](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.68...v3.8.0-beta.69) (2024-04-03)

Note: Version bump only for package ohif-docs

[3.8.0-beta.68](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.67...v3.8.0-beta.68) (2024-04-03)

Features

  • segmentation: Enhanced segmentation panel design for TMTV (#3988) (9f3235f)

[3.8.0-beta.67](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.66...v3.8.0-beta.67) (2024-04-02)

Features

  • ViewportActionMenu: window level per viewport / new patient info / colorbars/ 3D presets and 3D volume rendering (#3963) (b7f90e3)

[3.8.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.65...v3.8.0-beta.66) (2024-03-28)

Note: Version bump only for package ohif-docs

[3.8.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.64...v3.8.0-beta.65) (2024-03-28)

Features

  • layout: new layout selector with 3D volume rendering (#3923) (617043f)

[3.8.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.63...v3.8.0-beta.64) (2024-03-27)

Features

  • toolbar: new Toolbar to enable reactive state synchronization (#3983) (566b25a)

[3.8.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.62...v3.8.0-beta.63) (2024-03-25)

Features

[3.8.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.61...v3.8.0-beta.62) (2024-03-19)

Note: Version bump only for package ohif-docs

[3.8.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.60...v3.8.0-beta.61) (2024-03-18)

Note: Version bump only for package ohif-docs

[3.8.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.59...v3.8.0-beta.60) (2024-03-15)

Note: Version bump only for package ohif-docs

[3.8.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.58...v3.8.0-beta.59) (2024-03-08)

Note: Version bump only for package ohif-docs

[3.8.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.57...v3.8.0-beta.58) (2024-03-05)

Note: Version bump only for package ohif-docs

[3.8.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.56...v3.8.0-beta.57) (2024-02-28)

Bug Fixes

[3.8.0-beta.56](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.55...v3.8.0-beta.56) (2024-02-22)

Note: Version bump only for package ohif-docs

[3.8.0-beta.55](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.54...v3.8.0-beta.55) (2024-02-21)

Features

  • resize: Optimize resizing process and maintain zoom level (#3889) (b3a0faf)

[3.8.0-beta.54](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.53...v3.8.0-beta.54) (2024-02-14)

Note: Version bump only for package ohif-docs

[3.8.0-beta.53](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.52...v3.8.0-beta.53) (2024-02-05)

Note: Version bump only for package ohif-docs

[3.8.0-beta.52](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.51...v3.8.0-beta.52) (2024-01-22)

Note: Version bump only for package ohif-docs

[3.8.0-beta.51](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.50...v3.8.0-beta.51) (2024-01-22)

Note: Version bump only for package ohif-docs

[3.8.0-beta.50](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.49...v3.8.0-beta.50) (2024-01-22)

Note: Version bump only for package ohif-docs

[3.8.0-beta.49](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.48...v3.8.0-beta.49) (2024-01-19)

Note: Version bump only for package ohif-docs

[3.8.0-beta.48](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.47...v3.8.0-beta.48) (2024-01-17)

Note: Version bump only for package ohif-docs

[3.8.0-beta.47](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.46...v3.8.0-beta.47) (2024-01-12)

Note: Version bump only for package ohif-docs

[3.8.0-beta.46](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.45...v3.8.0-beta.46) (2024-01-12)

Note: Version bump only for package ohif-docs

[3.8.0-beta.45](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.44...v3.8.0-beta.45) (2024-01-09)

Note: Version bump only for package ohif-docs

[3.8.0-beta.44](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.43...v3.8.0-beta.44) (2024-01-09)

Features

  • transferSyntax: prefer server transcoded transfer syntax for all images (#3883) (1456a49)

[3.8.0-beta.43](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.42...v3.8.0-beta.43) (2024-01-09)

Bug Fixes

  • segmentation: upgrade cs3d to fix various segmentation bugs (#3885) (b1efe40)

[3.8.0-beta.42](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.41...v3.8.0-beta.42) (2024-01-08)

Note: Version bump only for package ohif-docs

[3.8.0-beta.41](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.40...v3.8.0-beta.41) (2024-01-08)

Features

[3.8.0-beta.40](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.39...v3.8.0-beta.40) (2024-01-08)

Note: Version bump only for package ohif-docs

[3.8.0-beta.39](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.38...v3.8.0-beta.39) (2024-01-08)

Note: Version bump only for package ohif-docs

[3.8.0-beta.38](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.37...v3.8.0-beta.38) (2024-01-08)

Note: Version bump only for package ohif-docs

[3.8.0-beta.37](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.36...v3.8.0-beta.37) (2024-01-08)

Note: Version bump only for package ohif-docs

[3.8.0-beta.36](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.35...v3.8.0-beta.36) (2023-12-15)

Note: Version bump only for package ohif-docs

[3.8.0-beta.35](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.34...v3.8.0-beta.35) (2023-12-14)

Note: Version bump only for package ohif-docs

[3.8.0-beta.34](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.33...v3.8.0-beta.34) (2023-12-13)

Note: Version bump only for package ohif-docs

[3.8.0-beta.33](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.32...v3.8.0-beta.33) (2023-12-13)

Note: Version bump only for package ohif-docs

[3.8.0-beta.32](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.31...v3.8.0-beta.32) (2023-12-13)

Note: Version bump only for package ohif-docs

[3.8.0-beta.31](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.30...v3.8.0-beta.31) (2023-12-13)

Note: Version bump only for package ohif-docs

[3.8.0-beta.30](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.29...v3.8.0-beta.30) (2023-12-13)

Note: Version bump only for package ohif-docs

[3.8.0-beta.29](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.28...v3.8.0-beta.29) (2023-12-13)

Features

  • config: Add activateViewportBeforeInteraction parameter for viewport interaction customization (#3847) (f707b4e)

[3.8.0-beta.28](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.27...v3.8.0-beta.28) (2023-12-08)

Note: Version bump only for package ohif-docs

[3.8.0-beta.27](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.26...v3.8.0-beta.27) (2023-12-06)

Bug Fixes

  • auth: fix the issue with oauth at a non root path (#3840) (6651008)

[3.8.0-beta.26](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.25...v3.8.0-beta.26) (2023-11-28)

Note: Version bump only for package ohif-docs

[3.8.0-beta.25](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.24...v3.8.0-beta.25) (2023-11-27)

Note: Version bump only for package ohif-docs

[3.8.0-beta.24](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.23...v3.8.0-beta.24) (2023-11-24)

Note: Version bump only for package ohif-docs

[3.8.0-beta.23](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.22...v3.8.0-beta.23) (2023-11-24)

Features

[3.8.0-beta.22](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.21...v3.8.0-beta.22) (2023-11-21)

Note: Version bump only for package ohif-docs

[3.8.0-beta.21](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.20...v3.8.0-beta.21) (2023-11-21)

Note: Version bump only for package ohif-docs

[3.8.0-beta.20](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.19...v3.8.0-beta.20) (2023-11-21)

Note: Version bump only for package ohif-docs

[3.8.0-beta.19](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.18...v3.8.0-beta.19) (2023-11-18)

Features

  • docs: Added various training videos to support the OHIF CLI tools (#3794) (d83beb7)

[3.8.0-beta.18](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.17...v3.8.0-beta.18) (2023-11-15)

Features

  • url: Add SeriesInstanceUIDs wado query param (#3746) (b694228)

[3.8.0-beta.17](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.16...v3.8.0-beta.17) (2023-11-13)

Note: Version bump only for package ohif-docs

[3.8.0-beta.16](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.15...v3.8.0-beta.16) (2023-11-13)

Note: Version bump only for package ohif-docs

[3.8.0-beta.15](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.14...v3.8.0-beta.15) (2023-11-10)

Features

  • dicomJSON: Add Loading Other Display Sets and JSON Metadata Generation script (#3777) (43b1c17)

[3.8.0-beta.14](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.13...v3.8.0-beta.14) (2023-11-10)

Bug Fixes

[3.8.0-beta.13](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.12...v3.8.0-beta.13) (2023-11-09)

Note: Version bump only for package ohif-docs

[3.8.0-beta.12](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.11...v3.8.0-beta.12) (2023-11-08)

Note: Version bump only for package ohif-docs

[3.8.0-beta.11](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.10...v3.8.0-beta.11) (2023-11-08)

Features

  • hp callback: Add viewport ready callback (#3772) (bf252bc)

[3.8.0-beta.10](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.9...v3.8.0-beta.10) (2023-11-03)

Note: Version bump only for package ohif-docs

[3.8.0-beta.9](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.8...v3.8.0-beta.9) (2023-11-02)

Note: Version bump only for package ohif-docs

[3.8.0-beta.8](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.7...v3.8.0-beta.8) (2023-10-31)

Note: Version bump only for package ohif-docs

[3.8.0-beta.7](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.6...v3.8.0-beta.7) (2023-10-30)

Note: Version bump only for package ohif-docs

[3.8.0-beta.6](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.5...v3.8.0-beta.6) (2023-10-25)

Bug Fixes

  • toolbar: allow customizable toolbar for active viewport and allow active tool to be deactivated via a click (#3608) (dd6d976)

[3.8.0-beta.5](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.4...v3.8.0-beta.5) (2023-10-24)

Bug Fixes

  • sr: dcm4chee requires the patient name for an SR to match what is in the original study (#3739) (d98439f)

[3.8.0-beta.4](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.3...v3.8.0-beta.4) (2023-10-23)

Note: Version bump only for package ohif-docs

[3.8.0-beta.3](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.2...v3.8.0-beta.3) (2023-10-23)

Note: Version bump only for package ohif-docs

[3.8.0-beta.2](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.1...v3.8.0-beta.2) (2023-10-19)

Bug Fixes

  • cine: Use the frame rate specified in DICOM and optionally auto play cine (#3735) (d9258ec)

[3.8.0-beta.1](https://github.com/OHIF/Viewers/compare/v3.8.0-beta.0...v3.8.0-beta.1) (2023-10-19)

Note: Version bump only for package ohif-docs

[3.8.0-beta.0](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.110...v3.8.0-beta.0) (2023-10-12)

Note: Version bump only for package ohif-docs

[3.7.0-beta.110](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.109...v3.7.0-beta.110) (2023-10-11)

Note: Version bump only for package ohif-docs

[3.7.0-beta.109](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.108...v3.7.0-beta.109) (2023-10-11)

Bug Fixes

  • export: wrong export for the tmtv RT function (#3715) (a3f2a1a)

[3.7.0-beta.108](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.107...v3.7.0-beta.108) (2023-10-10)

Note: Version bump only for package ohif-docs

[3.7.0-beta.107](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.106...v3.7.0-beta.107) (2023-10-10)

Note: Version bump only for package ohif-docs

[3.7.0-beta.106](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.105...v3.7.0-beta.106) (2023-10-10)

Bug Fixes

  • segmentation: Various fixes for segmentation mode and other (#3709) (a9a6ad5)

[3.7.0-beta.105](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.104...v3.7.0-beta.105) (2023-10-10)

Note: Version bump only for package ohif-docs

[3.7.0-beta.104](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.103...v3.7.0-beta.104) (2023-10-09)

Note: Version bump only for package ohif-docs

[3.7.0-beta.103](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.102...v3.7.0-beta.103) (2023-10-09)

Note: Version bump only for package ohif-docs

[3.7.0-beta.102](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.101...v3.7.0-beta.102) (2023-10-06)

Note: Version bump only for package ohif-docs

[3.7.0-beta.101](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.100...v3.7.0-beta.101) (2023-10-06)

Bug Fixes

  • bugs: fixing lots of bugs regarding release candidate (#3700) (8bc12a3)

[3.7.0-beta.100](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.99...v3.7.0-beta.100) (2023-10-06)

Note: Version bump only for package ohif-docs

[3.7.0-beta.99](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.98...v3.7.0-beta.99) (2023-10-04)

Note: Version bump only for package ohif-docs

[3.7.0-beta.98](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.97...v3.7.0-beta.98) (2023-10-04)

Note: Version bump only for package ohif-docs

[3.7.0-beta.97](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.96...v3.7.0-beta.97) (2023-10-04)

Note: Version bump only for package ohif-docs

[3.7.0-beta.96](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.95...v3.7.0-beta.96) (2023-10-04)

Note: Version bump only for package ohif-docs

[3.7.0-beta.95](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.94...v3.7.0-beta.95) (2023-10-04)

Note: Version bump only for package ohif-docs

[3.7.0-beta.94](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.93...v3.7.0-beta.94) (2023-10-03)

Note: Version bump only for package ohif-docs

[3.7.0-beta.93](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.92...v3.7.0-beta.93) (2023-10-03)

Features

  • displayArea: add display area to hanging protocol (#3691) (5e7fe91)

[3.7.0-beta.92](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.91...v3.7.0-beta.92) (2023-10-03)

Note: Version bump only for package ohif-docs

[3.7.0-beta.91](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.90...v3.7.0-beta.91) (2023-10-03)

Note: Version bump only for package ohif-docs

[3.7.0-beta.90](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.89...v3.7.0-beta.90) (2023-10-03)

Note: Version bump only for package ohif-docs

[3.7.0-beta.89](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.88...v3.7.0-beta.89) (2023-10-03)

Note: Version bump only for package ohif-docs

[3.7.0-beta.88](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.87...v3.7.0-beta.88) (2023-10-03)

Bug Fixes

  • config: support more values for the useSharedArrayBuffer (#3688) (1129c15)

[3.7.0-beta.87](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.86...v3.7.0-beta.87) (2023-09-29)

Bug Fixes

  • no sab: should work when shared array buffer is not required (#3686) (a67d72d)

[3.7.0-beta.86](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.85...v3.7.0-beta.86) (2023-09-29)

Bug Fixes

  • cli: various fixes for adding custom modes and extensions (#3683) (dc73b18)

[3.7.0-beta.85](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.84...v3.7.0-beta.85) (2023-09-26)

Note: Version bump only for package ohif-docs

[3.7.0-beta.84](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.83...v3.7.0-beta.84) (2023-09-26)

Note: Version bump only for package ohif-docs

[3.7.0-beta.83](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.82...v3.7.0-beta.83) (2023-09-26)

Note: Version bump only for package ohif-docs

[3.7.0-beta.82](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.81...v3.7.0-beta.82) (2023-09-26)

Note: Version bump only for package ohif-docs

[3.7.0-beta.81](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.80...v3.7.0-beta.81) (2023-09-26)

Note: Version bump only for package ohif-docs

[3.7.0-beta.80](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.79...v3.7.0-beta.80) (2023-09-22)

Features

  • segmentation mode: Add create, and export SEG with Brushes (#3632) (48bbd62)

[3.7.0-beta.79](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.78...v3.7.0-beta.79) (2023-09-22)

Performance Improvements

  • memory: add 16 bit texture via configuration - reduces memory by half (#3662) (2bd3b26)

[3.7.0-beta.78](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.77...v3.7.0-beta.78) (2023-09-21)

Note: Version bump only for package ohif-docs

[3.7.0-beta.77](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.76...v3.7.0-beta.77) (2023-09-21)

Note: Version bump only for package ohif-docs

[3.7.0-beta.76](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.75...v3.7.0-beta.76) (2023-09-19)

Bug Fixes

  • keyCloak: fix openresty keycloak deployment recipe (#3655) (2d7721c)

[3.7.0-beta.75](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.74...v3.7.0-beta.75) (2023-09-18)

Note: Version bump only for package ohif-docs

[3.7.0-beta.74](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.73...v3.7.0-beta.74) (2023-09-15)

Note: Version bump only for package ohif-docs

[3.7.0-beta.73](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.72...v3.7.0-beta.73) (2023-09-12)

Note: Version bump only for package ohif-docs

[3.7.0-beta.72](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.71...v3.7.0-beta.72) (2023-09-12)

Note: Version bump only for package ohif-docs

[3.7.0-beta.71](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.70...v3.7.0-beta.71) (2023-09-12)

Note: Version bump only for package ohif-docs

[3.7.0-beta.70](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.69...v3.7.0-beta.70) (2023-09-12)

Note: Version bump only for package ohif-docs

[3.7.0-beta.69](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.68...v3.7.0-beta.69) (2023-09-11)

Note: Version bump only for package ohif-docs

[3.7.0-beta.68](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.67...v3.7.0-beta.68) (2023-09-11)

Note: Version bump only for package ohif-docs

[3.7.0-beta.67](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.66...v3.7.0-beta.67) (2023-09-06)

Note: Version bump only for package ohif-docs

[3.7.0-beta.66](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.65...v3.7.0-beta.66) (2023-09-06)

Note: Version bump only for package ohif-docs

[3.7.0-beta.65](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.64...v3.7.0-beta.65) (2023-09-06)

Note: Version bump only for package ohif-docs

[3.7.0-beta.64](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.63...v3.7.0-beta.64) (2023-09-05)

Bug Fixes

  • nginx archive recipe: Fixes to various configuration files. (#3624) (3ce7225)

[3.7.0-beta.63](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.62...v3.7.0-beta.63) (2023-09-01)

Features

  • grid: remove viewportIndex and only rely on viewportId (#3591) (4c6ff87)

[3.7.0-beta.62](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.61...v3.7.0-beta.62) (2023-08-30)

Note: Version bump only for package ohif-docs

[3.7.0-beta.61](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.60...v3.7.0-beta.61) (2023-08-29)

Note: Version bump only for package ohif-docs

[3.7.0-beta.60](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.59...v3.7.0-beta.60) (2023-08-29)

Note: Version bump only for package ohif-docs

[3.7.0-beta.59](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.58...v3.7.0-beta.59) (2023-08-29)

Note: Version bump only for package ohif-docs

[3.7.0-beta.58](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.57...v3.7.0-beta.58) (2023-08-25)

Features

  • cloud data source config: GUI and API for configuring a cloud data source with Google cloud healthcare implementation (#3589) (a336992)

[3.7.0-beta.57](https://github.com/OHIF/Viewers/compare/v3.7.0-beta.56...v3.7.0-beta.57) (2023-08-23)

Note: Version bump only for package ohif-docs


Platform Docs Docs Conformance (`platform/docs/docs/conformance.md`)


You can find a version that has been open sourced by Radical Imaging in this link


Platform Docs Docs Release Notes (`platform/docs/docs/release-notes.md`)


Release Notes

You can find the detailed release notes on the OHIF website. Please visit https://ohif.org/release-notes


Platform Docs Docs Resources (`platform/docs/docs/resources.md`)


Resources

Throughout the development of the OHIF Viewer, we have participated in various
conferences and "hackathons". In this page, we will provide the presentations
and other resources that we have provided to the community in the past:

2025

Machine Learning in Medical Imaging Consortium (MaLMIC) | January 2025

We presented two talks at the Machine Learning in Medical Imaging Consortium (MaLMIC) 2025 conference.

  • Advanced Medical Imaging Visualization Slides
  • Introducing Advanced Segmentation Tools in the OHIF Viewer and Cornerstone3D Slides

2024

ITCR Sustainment Session 2024

Dr. Gordon Harris presented at ITCR sustainment session about the future of OHIF.

ITCR Sustainment Panel 2024

  • Advanced Medical Imaging Visualization Slides

IMNO 2024 - March 19-20, 2024

We participated in the Imaging Network Ontario (ImNO) 2024 symposium, presenting three posters. One of our presentations received the best talk award during the session.

  • Advancing Medical Imaging on the Web: Implementation of Hanging Protocols for Automated Image Display Configuration in OHIF V3 Poster
  • Advancing Medical Imaging on the Web: Optimizing the Dicomweb Server Architecture with Static Dicomweb Poster
  • (🏆🏆 BEST PRESENTATION AWARD in the Session 7 Pitches: Devices, HW, SW Development 🏆🏆) Advancing Medical Imaging on the Web: Integrating High Throughput JPEG 2000 (HTJ2K) in Cornerstone3D for Streamlined Progressive Loading and Visualization Poster

2023

ITCR 2023 Conference | September 11-13, 2023

Dr. Gordon Harris presented an update on OHIF in NCI Informatics Technology for Cancer Research Annual Meeting. You can find the slides and poster here:
[Slides][Poster]

SIIM 2023 Tech Tools Webinar | April 12th, 2023

Free, Open Source Tools for Research: MONAI and OHIF Viewer
[Slides][Video]

NA-MIC Project Week 38th 2023 - Remote

We participated in the 38th Project Week with three projects around OHIF. [Website]

  • PolySeg representations for OHIF Viewer (link)
  • Cross study synchronizer for OHIF Crosshair (link)
  • DATSCAN Viewer implementation in OHIF (link)

2022

OHIF Demo to Interns

[Slides]

SIIM 2022 - Updates from the Imaging Informatics Community

We participated in the SIIM 2022 conference to give update for the imaging
informatics community.
[Slides]
[Video]

The Imaging Network Ontario - Remote

The Imaging Network Ontario (ImNO) is an annual symposium that brings together
medical imaging researchers and scientists from across Canada to share
knowledge, ideas, and experiences.
[Slides]
[Video]

[NA-MIC Project Week 36th 2022 - Remote](https://github.com/NA-MIC/ProjectWeek/blob/master/PW36_2022_Virtual/README.md)

The Project Week is a week-long hackathon of hands-on activity in which medical
image computing researchers. OHIF team participated and gave a talk on OHIF and
Cornerstone in the 36th Project Week:
[Slides]
[Video]

2021

[NA-MIC Project Week 35th 2021 - Remote](https://github.com/NA-MIC/ProjectWeek/tree/master/PW35_2021_Virtual)

The Project Week is a week-long hackathon of hands-on activity in which medical
image computing researchers. OHIF team participated in the 35th Project Week
in 2021.
[Slides]

Chan Zuckerberg Initiative (CZI)

Project presentations and demonstrations of Essential Open Source Software for
Science (EOSS) grantees
[Slides]
[Video]

Google Cloud Tech

Healthcare Imaging with Cloud Healthcare API
[Video]

2020

OHIF ITCR Pitch

OHIF pitch for Informatics Technology for Cancer Research (ITCR)
[Slides]
[Video]

2019

OHIF and VTK.js Training Course

OHIF and Kitware collaboration to create a training course for OHIF and VTK.js
developers. Funding for this work was provided by Kitware (NIH NINDS
R44NS081792, NIH NINDS R42NS086295, NIH NIBIB and NIGMS R01EB021396, NIH NIBIB
R01EB014955), Isomics (NIH P41 EB015902), and Massachusetts General Hospital
(NIH U24 CA199460).

  1. Introduction to VTK.js and OHIF
    [Slides]
    [Video]
  2. Developing with VTK.js
    [Slides]
    [Video]
  3. VTK.js Architecture and Tooling
    [Slides]
    [Video]
  4. OHIF + VTK.js Integration
    [Slides]
    [Video]

2017

Lesion Tracker

LesionTracker: Extensible Open-Source Zero-Footprint Web Viewer for Cancer
Imaging Research and Clinical Trials. This project was supported in part by
grant U24 CA199460 from the National Cancer Institute (NCI) Informatics
Technology for Cancer Research (ITCR) Program.
[Video]

OHIF Community Meeting - June

[Slides]

2016

Imaging Community Call

Open Source Oncology Web Viewer; Presentation by Gordon J. Harris
[Slides]

OHIF Community Meeting - June

[Slides]

OHIF Community Meeting - September

[Slides]


Platform Docs Docs Test Coverage (`platform/docs/docs/test-coverage.md`)


Test Coverage

Playwright

Here's the test coverage report for our Playwright tests. Keep in mind that this doesn't include our Cypress tests, so our actual test coverage is likely higher than what's shown. We're focusing on Playwright for future OHIF testing, and we're really pushing to improve that coverage number.

You can view our latest test coverage report here:


Platform Docs Docs Behaviours Report Dialog Save Destinations (`platform/docs/docs/behaviours/report-dialog-save-destinations.md`)

Report dialog: where a save goes, and what the series is called

Status: Implemented — current behaviour

The report dialog stores a segmentation, a contour set, or a measurement report.
The dialog asks the user two things: which series the object goes into, and what
that series is called.

Implemented across:

  • extensions/default/src/customizations/reportDialogCustomization.tsx — the
    dialog, and the ohif.createReportDialog customization.
  • extensions/default/src/Panels/createReportDialogPrompt.tsx — the prompt that
    shows the dialog, and the input and the output of the prompt.
  • extensions/default/src/utils/seriesDescriptionHistory.ts — the descriptions
    that the viewer remembers.
  • extensions/cornerstone-dicom-seg/src/commandsModule.ts — storeSegmentation,
    the SEG caller and the RTSTRUCT caller.
  • extensions/default/src/utils/promptSaveReport.tsx — the measurement report
    caller.
  • libs/@cornerstonejs/packages/adapters/src/utilities/referencedMetadataProvider.ts
    — the PredecessorSequence provider, which reads the predecessor instance.

One save stores one object

Each destination stores all of the current data as one object, and the dialog
merges nothing. A save into a series that already holds data does not read that
data, and the save leaves no part of the current data out. The destination
decides which series holds the new object, and therefore which instance the new
object supersedes. The earlier instances stay in the series, and the new
instance becomes the one that the viewer loads by default.

The three destinations

Destination Where the object goes When the dialog offers the destination
Save to current The series that the viewer loaded the data from The predecessorImageId of the data names a loaded series
Save as new A new series, with an editable number and description Always
Replace existing Another loaded series of this modality, which the user selects The viewer holds at least one other such series

Save to current is the default choice when the dialog offers it, and
Save as new is the default choice otherwise. Save to current and
Replace existing keep the number and the description of the target series, so
the dialog does not let the user edit either one.

Which series the dialog offers

The dialog offers a loaded series as a destination only when both of these hold:

  1. The series holds the same type of object, which is the modality of the save.
  2. The series has a predecessorImageId value.

The predecessorImageId value names the immediate prior object that someone
saved into the series. The save supersedes that one instance. The adapter reads
the series and the instance number through the value, from the
PredecessorSequence provider.

The dialog does not fall back to the SeriesInstanceUID value of the display
set. A UID names a series and not an instance, so a UID names no prior object,
and a UID is not an image id. The provider finds no instance for a UID, and the
save then starts a new series rather than extending the chosen one.

A local id, such as dicomfile:3, is a valid value. The viewer registers an
uploaded instance under a local id, and the provider resolves a local id, so a
user can save against an uploaded instance more than once.

A display set that the viewer downloaded and never stored has no
predecessorImageId value, and the dialog does not offer that display set. The
number of a new series still counts such a series, because the number comes from
every loaded series of the modality and not from the offered ones alone.

What the new series is called

Save as new offers four names, and the field starts from the first name that is
not blank:

  1. itemName, the name that the user chose for the item. A rename before the
    save therefore reaches the field. storeSegmentation passes
    segmentation.label, but only when the user chose that label: the service
    invents a name such as Segmentation 3 for a new segmentation, and marks the
    segmentation with labelIsGenerated. A label that is still marked this way
    goes to defaultSeriesDescription instead, so a generated name does not
    outrank the remembered descriptions. A rename clears the mark, and the save
    compares no two strings, so a user who types the invented name still gets the
    name in itemName.
  2. The description of the series that the viewer loaded the data from, which is
    the name of the last save of this data.
  3. The descriptions that the user used before for this type of item, most recent
    first. See remembered descriptions.
  4. defaultSeriesDescription, the name for an item that has no other name. The
    in-tree callers pass Segmentation, Contours and Measurements.

The pull-down holds the four names in that order. A blank name, and a name of
spaces, drops out of the list, so such a name cannot hide a later name. The
dialog compares the names without case, and the list holds each name once. An
emptied field falls back to the first name of the list.

A caller with no editable name passes no itemName: the measurement report has
no such name, and the report therefore starts from the description of the loaded
series, or from the last used name.

Remembered descriptions

The viewer remembers a description when the user creates a new series with the
description, and a download counts as a save. A save into a series that already
exists remembers nothing, because that series keeps its own description.

The history holds a name that the user chose. A save that uses
defaultSeriesDescription remembers nothing, because the caller supplies that
name at every save, and the dialog offers the name in any case. A generated
segmentation label reaches defaultSeriesDescription, so Segmentation 1 stays
out of the history and the dialog cannot offer Segmentation 1 as the name of a
later, unrelated segmentation.

  • itemType is the key that the viewer remembers the descriptions under, and
    itemType defaults to the modality.
  • rememberedDescriptionCount is how many descriptions the viewer remembers, and
    the count defaults to 5.
  • A count of 0 turns the history off. The list then holds one name, and the
    dialog does not render the pull-down.

The user reaches the list in three ways: the pull-down button shows every name;
typing narrows the list to the names that the typing can complete; Tab
completes to the first of those names, and the arrow keys plus Enter select
one.

The series number of a new series

The dialog offers one past the highest series number of the loaded series of this
modality, and at least minSeriesNumber. The user can edit the number. An empty
number, and a number that is not valid, falls back to the offered number.

createReportDialogPrompt returns seriesNumber, and also
priorSeriesNumber, which is one less. A caller that computes the number as
1 + priorSeriesNumber gets the number that the dialog shows.


Platform Docs Docs Behaviours Segmentation Multiframe Part10 Prefetch (`platform/docs/docs/behaviours/segmentation-multiframe-part10-prefetch.md`)

Full-instance prefetch for segmentation (and multiframe) loading

Status: Implemented — enabled and awaited to completion by default;
per-frame loading is the explicit opt-out

The boolean loadMultiframeAsPart10 resolves, in order: the data source
configuration, the global customization
cornerstone.segmentation.loadMultiframeAsPart10, then the built-in default of
true — i.e. by default the SEG load waits for the whole-instance
fetch+parse to complete or fail
(deliberately no timeout) and serves every
frame from the registry. Set loadMultiframeAsPart10: false explicitly to
force per-frame loading — the exception, for back ends that need to fetch the
individual images instead (e.g. servers that cannot serve a whole-instance
retrieve, or deployments where holding the full Part 10 object in memory is
undesirable). A failed or unsupported instance fetch resolves quickly and
falls back to per-frame regardless of the setting, so it never wedges the load.

Note the per-frame endpoint itself is not inefficient — each frame request is
cheap — but SEG frames are so small and numerous that one bulk Part 10 fetch
beats hundreds of tiny requests (see Problem below). This holds even for very
large SEG objects (hundreds of MB): any finite race cap would simply expire on
those and storm per-frame anyway while abandoning the bulk fetch's benefit,
which is why there is no timeout.

Implemented across:

  • @cornerstonejs/dicom-image-loader
    • imageLoader/prefetchPart10Instance.ts — registers a Part 10 instance into
      the frame registry (thin wrapper over addDicomPart10Instance).
    • imageLoader/wadors/loadImageFromRegistry.ts +
      wadors/loadImage.ts — WADO-RS loads now consult the registry first.
  • @ohif/extension-default DicomWebDataSource — retrieve.prefetchInstanceFrames.
  • @ohif/extension-cornerstone-dicom-seg getSopClassHandlerModule.ts — call
    site (resolves the config and awaits the prefetch).

Related: @cornerstonejs/adapters labelmapImagesFromBuffer.ts
(decodeSegPixelDataFromFrameIds, bounded by concurrency, default 16).

Problem

The SEG load path now fetches/decodes frames through the cornerstone image
loader, one loadable imageId per frame, parallelized up to N=16
(concurrency). For a SEG (or any multiframe instance) with 800+ small
frames
, this means 800+ independent HTTP requests, each with its own
request/response overhead. Even at 16-wide concurrency the per-request latency
floor dominates: each frame is < 1 KB of payload but pays a full round trip.

Streaming one large object (the entire Part 10 / multiframe instance) is far
cheaper than streaming hundreds of tiny ones — a single connection, a single set
of headers, no per-frame TTFB. The whole instance for an 800-frame binary SEG is
typically a few hundred KB to a few MB.

Goal

Add a generic data-source capability that, just before the segmentation
loader runs, optionally fetches the entire original instance in one request
and registers it into the Cornerstone3D frame registry (the
@cornerstonejs/metadata NATURALIZED + COMPRESSED_FRAME_DATA framework, parsed
by the dcmjs async reader) — so the existing per-frame imageId fetch path
transparently hits local data instead of the network, while the cornerstone
decode path stays byte-for-byte identical
(same decompressor, same workers).

Crucially this is best-effort:

  • By default (loadMultiframeAsPart10 unset → true) the load waits for the
    full-instance fetch+parse to complete or fail
    — no timeout — then every
    frame is served from the registry.
  • If loadMultiframeAsPart10 resolves to false (explicitly configured), the
    capability is disabled — no full-instance fetch is attempted. Per-frame
    loading is the exception, opted into per deployment.
  • If the full-instance fetch or parse fails for any reason, it must never
    fail the segmentation decode. We log and fall back to per-frame fetches.

Why this is safe / transparent

There is one uniform frame registry: the Cornerstone3D @cornerstonejs/metadata
NATURALIZED framework
, populated by addDicomPart10Instance (which parses the
Part 10 with the dcmjs AsyncDicomReader) and read per-frame via the
COMPRESSED_FRAME_DATA typed provider. Frame imageIds are normalized to the base
instance by baseImageIdQueryFilter (strips /frames/N, ?frame=N, &frame=N),
so one registration under the instance serves every frame.

This is the same registry the WADO-URI / dicomweb loader already uses:
wadouri/loadImage.ts's loadImageFromNaturalizedMetadata resolves each frame
from COMPRESSED_FRAME_DATA and decodes it with createImage. The gap was that
WADO-RS (wadors/loadImage.ts) always issued a per-frame /frames/N request
and never consulted the registry. The adapter closes that gap:

  • wadors/loadImageFromRegistry.ts — loadImageFromCompressedFrameRegistry(imageId)
    looks up COMPRESSED_FRAME_DATA for the frame; if present it decodes via the
    same createImage path and returns the image; if absent it returns
    undefined.
  • wadors/loadImage.ts calls it first and short-circuits when the registry has
    the frame, otherwise falls through to the existing network path.

So once prefetchPart10Instance has registered the instance, both WADO-URI and
WADO-RS
serve every frame from the single registry, with the same decode
pipeline
(createImage → worker decoder). From cornerstone's perspective
nothing changed except the compressed bytes came from the registry instead of the
wire.

Rejected alternatives: (1) a bespoke Map registry plus
getPixelData shims — duplicates a registry that already exists; (2) seeding
the core image cache (cache.putImageLoadObject) per frame — works, but the
per-frame compressed data already lives in the NATURALIZED registry, so basing
the design on that registry (and teaching WADO-RS to read it) keeps a single
source of truth instead of copying frames into a second cache.

API (as implemented)

A generic capability on the data source's retrieve namespace (so it works for
any multiframe instance, not just SEG, and alternate data sources can override
it), plus the SEG handler call site that awaits it.

IWebApiDataSource.create passes retrieve through verbatim, so the capability
is added there (no @ohif/core change):

ts
// On the data source (DicomWebDataSource):
dataSource.retrieve.prefetchInstanceFrames({
  instance,                          // study/series/sop UIDs for retrieveInstance
  imageId,                           // SEG instance imageId (frame qualifiers normalized away)
}): {
  done: Promise<boolean>;            // resolves true if fetched+registered, false if skipped/failed
  cancel: () => void;
};

The implementation fetches the instance with wadoDicomWebClient.retrieveInstance
(which returns the Part 10 as an ArrayBuffer, unwrapping multipart/related
transparently) and passes a lazy resolver to
dicomImageLoader.prefetchPart10Instance(imageId, resolver). All work is wrapped
so any failure resolves done to false — it never throws into the loader.

Call site (just before the loader)

In getSopClassHandlerModule.ts, immediately before
createFromDicomSegImageId(...) (abridged from the actual code):

ts
const loadMultiframeAsPart10 =
  (dataSource?.getConfig?.()?.loadMultiframeAsPart10 as boolean | undefined) ??
  (customizationService?.getCustomization?.(
    'cornerstone.segmentation.loadMultiframeAsPart10'
  ) as boolean | undefined) ??
  true;

let prefetch;
if (loadMultiframeAsPart10) {
  prefetch = dataSource.retrieve?.prefetchInstanceFrames?.({
    instance,
    imageId: segImageIdForMetadata,
  });
  if (prefetch?.done) {
    // Wait for the bulk fetch to complete or fail — no timeout.
    await prefetch.done;
  }
}

try {
  results = await adaptersSEG.Cornerstone3D.Segmentation.createFromDicomSegImageId(
    imageIds,
    segImageIdForMetadata,
    { metadataProvider: metaData, tolerance, parserType, frameImageIds,
      concurrency: SEG_FRAME_DECODE_CONCURRENCY }
  );
} finally {
  eventTarget.removeEventListener(Enums.Events.SEGMENTATION_LOAD_PROGRESS, onProgress);
  prefetch?.cancel?.();
}

The SEG loader and adapter are unchanged — the loader still asks the image
loader for each frame. Registered frames resolve from the registry; the rest
fetch normally.

Mechanism (the 4 requested points)

1. Async DICOM reader (dcmjs) to parse the instance

Parsing is done by @cornerstonejs/metadata's addDicomPart10Instance, which
uses the dcmjs AsyncDicomReader (naturalizePart10Buffer in
naturalizedHandlers.ts) and understands encapsulated PixelData fragmentation,
so the NATURALIZED instance exposes pixel data as an array of per-frame
ArrayBuffer fragments. COMPRESSED_FRAME_DATA then slices out the requested
frame. We did not re-implement any parsing — the prefetch just feeds the fetched
Part 10 buffer to this existing reader.

Implemented as full-buffer v1: the whole instance is fetched, then parsed.
addDicomPart10Instance accepts a lazy resolver, so the fetch is what the race
waits on. Progressive/streaming registration (registering frames as bytes arrive)
is a future optimization — see rollout step 4.

The full-instance fetch can come back in two shapes, and the parser must
handle both before any DICOM parsing happens:

  • multipart/related — a WADO-RS instance retrieve
    (GET …/instances/{sop} with Accept: multipart/related; type="application/dicom")
    wraps the Part 10 object(s) in a MIME multipart envelope: leading part headers,
    a --boundary marker, the DICOM bytes, then a terminal --boundary--. The
    inner DICOM byte offsets are shifted by the MIME header length, so dcmjs
    must be fed the unwrapped inner part, never the raw response.
  • raw DICOM — WADO-URI, a direct file/object URL, or a bulkDataURI that
    returns a single application/dicom body: the response is the Part 10
    bytes, no envelope.

As implemented, the full-buffer path delegates this to dicomweb-client's
retrieveInstance
, which performs the WADO-RS instance retrieve and returns the
Part 10 as an ArrayBuffer with the multipart/related envelope already
unwrapped (and returns the single-part body as-is). prefetchInstanceFrames
additionally tolerates an [ArrayBuffer] or ArrayBufferView shape defensively.
So the implemented path is:

text
retrieveInstance() → ArrayBuffer (multipart unwrapped by dicomweb-client)
                   → prefetchPart10Instance → addDicomPart10Instance → dcmjs AsyncDicomReader

Detection by Content-Type and manual unwrapping (the approach wadors/extractMultipart.ts
uses: contentType.indexOf('multipart') === -1 → bytes as-is; else strip the
boundary/part headers) becomes relevant only for the future streaming path
(rollout step 4), where these wrinkles must be handled directly:

  • The multipart preamble/boundary stripped at the start of the stream and the
    terminal boundary detected at the end; a boundary token can straddle chunk
    boundaries
    , so the unwrapper must buffer across chunks (the existing
    findIndexOfString + tokenIndex carry-over in extractMultipart is built for
    incremental calls).
  • multipart/related may contain multiple parts; a single-instance retrieve
    yields one — guard for >1.
  • A truncated/partial body (no terminal boundary yet) must not be mis-parsed.

2. Register the compressed data into the frame registry

The fetched Part 10 buffer is registered once per instance via the
prefetchPart10Instance adapter (a thin wrapper over addDicomPart10Instance):

ts
// @cornerstonejs/dicom-image-loader: imageLoader/prefetchPart10Instance.ts
import { utilities } from '@cornerstonejs/metadata';
const { addDicomPart10Instance } = utilities;

export function prefetchPart10Instance(baseImageId, part10 /* buffer | resolver */) {
  return addDicomPart10Instance(baseImageId, part10);
}

That populates NATURALIZED for the instance; COMPRESSED_FRAME_DATA then yields
each frame's compressed bytes + transfer syntax on demand. Frame imageIds
normalize to the instance key automatically (baseImageIdQueryFilter), so there
is no per-frame registration loop and no second cache to keep coherent — the
registry is the existing NATURALIZED framework.

The "few new adapters" the task calls for:

  1. prefetchPart10Instance(baseImageId, part10) — entry point to register a
    fetched instance into the registry (exported from
    @cornerstonejs/dicom-image-loader).
  2. loadImageFromCompressedFrameRegistry(imageId, options) in
    wadors/loadImageFromRegistry.ts — teaches the WADO-RS loader to read the
    registry. It looks up COMPRESSED_FRAME_DATA for the frame and, if present,
    decodes via the same createImage the network path uses; wadors/loadImage.ts
    calls it first and short-circuits on a hit. (WADO-URI already reads the
    registry via loadImageFromNaturalizedMetadata.)

Metadata the decoder needs (imagePixelModule, transfer syntax) comes from the
same NATURALIZED instance, plus the SEG handler's existing
_ensureSegInstanceMetadataAvailable per frame imageId.

3. Cornerstone uses its existing decompressor — identical downstream

Both the WADO-URI path and the new WADO-RS registry path decode via
createImage (→ the same web-worker decoder used for every network frame), so
encapsulated transfer syntaxes are decompressed exactly as if fetched per-frame
and native/uncompressed frames pass through unchanged. No new decode path, no
codec changes, no divergence in pixel output — the only difference is that the
compressed bytes came from the registry instead of the wire.

4. Failure is non-fatal — fall back to per-frame fetches

prefetchInstanceFrames wraps the fetch + parse so that any failure (network
error, cancel, parse error, unexpected retrieveInstance shape) resolves
done to false and logs a warning — it never throws into the SEG load. When
the registry has no data for a frame, loadImageFromCompressedFrameRegistry
returns undefined and the WADO-RS loader falls through to its normal
/frames/N request. So if the prefetch is slow, disabled, or fails, loading is
exactly today's per-frame behaviour.

Edge cases that degrade gracefully:

  • cancel() (viewport closed / segmentation removed mid-load) → the resolver
    throws on its cancelled flag; done resolves false; any already-registered
    data stays usable.
  • A misbehaving metadata provider → the registry lookup is wrapped in try/catch
    and returns undefined, so per-frame loading is never broken.

Semantics (the `loadMultiframeAsPart10` knob)

  • Unset (default) or true → start the full-instance fetch+parse and await
    it to completion or failure
    (await prefetch.done) — deliberately no
    timeout; every frame is then served from the registry. Fetch failure resolves
    done quickly, so unsupported servers fall straight through to per-frame.
  • false (explicitly configured) → disabled; per-frame loading is the
    exception, opted into per deployment.

addDicomPart10Instance registers the instance atomically (one parse), so
registration is all-or-nothing rather than progressive. Progressive
registration (rollout step 4) would let frames be served as they arrive.

There is no timeout because a bounded wait loses on exactly the objects where
the prefetch matters most: a large SEG (hundreds of MB) cannot finish inside
any small cap, so a capped race expires and storms per-frame anyway while
abandoning the bulk fetch's benefit. The only failure mode a timeout would
bound — a fetch that never settles — is already covered by the browser's
network-level failure surfacing through done.

Where the generic capability lives

  • The registry is the existing @cornerstonejs/metadata NATURALIZED framework
    — no new cache. New code in @cornerstonejs/dicom-image-loader is the thin
    adapter prefetchPart10Instance() plus the WADO-RS read path
    (wadors/loadImageFromRegistry.ts, wired into wadors/loadImage.ts).
  • The fetch + register orchestration lives in the data source
    (extensions/default/.../DicomWebDataSource → retrieve.prefetchInstanceFrames),
    because it knows how to retrieve a full instance (auth headers, wadoRoot,
    WADO-RS instance retrieve via dicomweb-client, CORS), and so alternate data
    sources can implement/override it.
  • The SEG handler only reads the configuration and awaits the prefetch.

This keeps the layering clean: data source = "how to get bytes", image loader =
"how to register/decode bytes", SEG handler = "when to ask".

Open questions / risks

  1. NATURALIZED registry key alignment. Both registration
    (addDicomPart10Instance) and the WADO-RS read normalize frame imageIds to the
    base instance via baseImageIdQueryFilter, so they agree. Worth a sanity check
    per data source that the SEG imageId passed to prefetchInstanceFrames and
    the frame imageIds the SEG loader requests share the same instance base.
  2. Memory. Holding the full instance plus the still-compressed frames in the
    registry raises memory for that instance until it is evicted. Compressed frames
    are small and decode is on-demand. Registry/cache eviction lifecycle for
    prefetched instances should be verified (especially repeated SEG loads).
  3. Streaming availability. v1 uses a single full-buffer retrieveInstance. A
    future streaming path (step 4) would register frames as bytes arrive.
  4. Auth / headers. Handled — the resolver sets
    wadoDicomWebClient.headers = getAuthorizationHeader() before retrieve, reusing
    the data source's existing decoration.
  5. Per-frame overhead. Every WADO-RS load now does one cheap
    COMPRESSED_FRAME_DATA lookup (a Map get after base normalization) before
    falling through. Negligible, and only short-circuits when an instance was
    actually prefetched.

Incremental rollout

  1. ✅ prefetchPart10Instance adapter + WADO-RS registry read
    (wadors/loadImageFromRegistry.ts) in dicom-image-loader. No behaviour change
    until something registers an instance.
  2. ✅ retrieve.prefetchInstanceFrames in DicomWebDataSource (full-buffer v1 via
    retrieveInstance); whether to call it is the caller's policy.
  3. ✅ SEG handler call site. Now enabled and awaited to completion by
    default
    (no timeout); per-frame loading requires an explicit
    loadMultiframeAsPart10: false.
  4. ⏳ Progressive (streaming) parse to register frames as they arrive (handle the
    multipart/related unwrap + boundary-straddle directly).
  5. ⏳ Extend to other multiframe loaders (the registry path is generic).

Platform Docs Docs Configuration ConfigurationFiles (`platform/docs/docs/configuration/configurationFiles.md`)


Config files

After following the steps outlined in
Getting Started, you'll notice that the
OHIF Viewer has data for several studies and their images. You didn't add this
data, so where is it coming from?

By default, the viewer is configured to connect to a Amazon S3 bucket that is hosting
a Static WADO server (see Static WADO DICOMWeb).
By default we use default.js for the configuration file. You can change this by setting the APP_CONFIG environment variable
and select other options such as config/local_orthanc.js or config/google.js.

Configuration Files

The configuration for our viewer is in the <root>platform/app/public/config
directory. Our build process knows which configuration file to use based on the
APP_CONFIG environment variable. By default, its value is
config/default.js. The majority of the viewer's features,
and registered extension's features, are configured using this file.

The simplest way is to update the existing default config:

js title="platform/app/public/config/default.js"
window.config = {
  routerBasename: null,
  extensions: [],
  modes: [],
  showStudyList: true,
  dataSources: [
    {
      namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
      sourceName: 'dicomweb',
      configuration: {
        friendlyName: 'dcmjs DICOMWeb Server',
        name: 'DCM4CHEE',
        wadoUriRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/wado',
        qidoRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs',
        wadoRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs',
        qidoSupportsIncludeField: true,
        supportsReject: true,
        imageRendering: 'wadors',
        thumbnailRendering: 'wadors',
        enableStudyLazyLoad: true,
        supportsFuzzyMatching: true,
        supportsWildcard: true,
        omitQuotationForMultipartRequest: true,
      },
    },
  ],
  defaultDataSourceName: 'dicomweb',
};

As you can see a new change in OHIF-v3 is the addition of dataSources. You
can build your own datasource and map it to the internal data structure of
OHIF’s > metadata and enjoy using other peoples developed mode on your own
data!

You can read more about data sources at
Data Source section in Modes

The configuration can also be written as a JS Function in case you need to
inject dependencies like external services:

js
window.config = ({ servicesManager } = {}) => {
  const { UIDialogService } = servicesManager.services;
  return {
    cornerstoneExtensionConfig: {
      tools: {
        ArrowAnnotate: {
          configuration: {
            getTextCallback: (callback, eventDetails) => UIDialogService.create({...
          }
        }
      },
    },
    routerBasename: null,
    dataSources: [
    {
      namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
      sourceName: 'dicomweb',
      configuration: {
        friendlyName: 'dcmjs DICOMWeb Server',
        name: 'DCM4CHEE',
        wadoUriRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/wado',
        qidoRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs',
        wadoRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs',
        qidoSupportsIncludeField: true,
        supportsReject: true,
        imageRendering: 'wadors',
        thumbnailRendering: 'wadors',
        enableStudyLazyLoad: true,
        supportsFuzzyMatching: true,
        supportsWildcard: true,
        omitQuotationForMultipartRequest: true,
      },
    },
  ],
  defaultDataSourceName: 'dicomweb',
  };
};

Configuration Options

Here are a list of some options available:

  • customizationService: An array of customization module references and inline overrides applied at the global scope. This is how deployers enable optional features like the Appearance & Theming system and configure UI components without modifying core code. See Customization Service for the full syntax reference.
  • disableEditing: If true, it disables editing in OHIF, hiding edit buttons in segmentation
    panel and locking already stored measurements.
  • maxNumberOfWebWorkers: The maximum number of web workers to use for
    decoding. Defaults to minimum of navigator.hardwareConcurrency and
    what is specified by maxNumberOfWebWorkers. Some windows machines require smaller values.
  • acceptHeader : accept header to request specific dicom transfer syntax ex : [ 'multipart/related; type=image/jls; q=1', 'multipart/related; type=application/octet-stream; q=0.1' ]
  • investigationalUseDialog: This should contain an object with option value, it can be either always which always shows the dialog once per session, never which never shows the dialog, or configure which shows the dialog once and won't show it again until a set number of days defined by the user, if it's set to configure, you are required to add an additional property days which is the number of days to wait before showing the dialog again.
  • groupEnabledModesFirst: boolean, if set to true, all valid modes for the study get grouped together first, then the rest of the modes. If false, all modes are shown in the order they are defined in the configuration.
  • experimentalStudyBrowserSort: boolean, if set to true, you will get the experimental StudyBrowserSort component in the UI, which displays a list of sort functions that the displaySets can be sorted by, the sort reflects in all part of the app including the thumbnail/study panel. These sort functions are defined in the customizationModule and can be expanded by users.
  • disableConfirmationPrompts: boolean, if set to true, it skips confirmation prompts for segmentation related prompts.
  • showPatientInfo: string, if set to 'visible', the patient info header will be shown and its initial state is expanded. If set to 'visibleCollapsed', the patient info header will be shown but it's initial state is collapsed. If set to 'disabled', the patient info header will never be shown, and if set to 'visibleReadOnly', the patient info header will be shown and always expanded.
  • requestTransferSyntaxUID : Request a specific Transfer syntax from dicom web server ex: 1.2.840.10008.1.2.4.80 (applied only if acceptHeader is not set)
  • omitQuotationForMultipartRequest: Some servers (e.g., .NET) require the multipart/related request to be sent without quotation marks. Defaults to false. If your server doesn't require this, then setting this flag to true might improve performance (by removing the need for preflight requests). Also note that
    if auth headers are used, a preflight request is required.
  • maxNumRequests: The maximum number of requests to allow in parallel. It is an object with keys of interaction, thumbnail, and prefetch. You can specify a specific number for each type. For thumbnail, a small pool (around 5) is recommended: the study list preview panel fetches a thumbnail per series in parallel, and a larger pool yields little throughput benefit while risking server overload and contention with interaction/prefetch requests.
  • modesConfiguration: Allows overriding modes configuration.
    • Example config:
    js
    modesConfiguration: {
        '@ohif/mode-longitudinal': {
          displayName: 'Custom Name',
          routeName: 'customRouteName',
            routes: [
              {
                path: 'customPath',
                layoutTemplate: () => {
                  /** Custom Layout */
                  return {
                    id: ohif.layout,
                    props: {
                      leftPanels: [tracked.thumbnailList],
                      rightPanels: [dicomSeg.panel, tracked.measurements],
                      rightPanelClosed: true,
                      viewports: [
                        {
                          namespace: tracked.viewport,
                          displaySetsToDisplay: [ohif.sopClassHandler],
                        },
                      ],
                    },
                  };
                },
              },
            ],
        }
      },

    Note: Although the mode configuration is passed to the mode factory function, it is up to the particular mode itself if its going to use it to allow overwriting its original configuration e.g.

    js
    function modeFactory({ modeConfiguration }) {
      return {
        id,
        routeName: 'viewer',
        displayName: 'Basic Viewer',
        ...
        onModeEnter: ({ servicesManager, extensionManager, commandsManager }) => {
          ...
        },
        /**
         * This mode allows its configuration to be overwritten by
         * destructuring the modeConfiguration value from the mode fatory function
         * at the end of the mode configuration definition.
         */
        ...modeConfiguration,
      };
    }
  • showLoadingIndicator: (default to true), if set to false, the loading indicator will not be shown when navigating between studies.
  • showStudyList: (default to false), if set to false, the OHIF search (or work list) page will not be shown nor will there be a back button (chevron) in the viewer to navigate to it
  • useNorm16Texture: (default to false), if set to true, it will use 16 bit data type for the image data wherever possible which has
    significant impact on reducing the memory usage. However, the 16Bit textures require EXT_texture_norm16 extension in webGL 2.0 (you can check if you have it here https://webglreport.com/?v=2). In addition to the extension, there are reported problems for Intel Macs that might cause the viewer to crash. In summary, it is great a configuration if you have support for it.
  • useSharedArrayBuffer (default to 'TRUE', options: 'AUTO', 'FALSE', 'TRUE', note that these are strings), for volume loading we use sharedArrayBuffer to be able to
    load the volume progressively as the data arrives (each webworker has the shared buffer and can write to it). However, there might be certain environments that do not support sharedArrayBuffer. In that case, you can set this flag to false and the viewer will use the regular arrayBuffer which might be slower for large volume loading.
  • supportsWildcard: (default to false), if set to true, the datasource will support wildcard matching for patient name and patient id.
  • allowMultiSelectExport: (default to false), if set to true, the user will be able to select the datasource to export the report to.
  • activateViewportBeforeInteraction: (default to true), if set to false, tools can be used directly without the need to click and activate the viewport.
  • autoPlayCine: (default to false), if set to true, data sets with the DICOM frame time tag (i.e. (0018,1063)) will auto play when displayed
  • addWindowLevelActionMenu: (default to true), if set to false, the window level action menu item is NOT added to the viewport action corners
  • showErrorDetails: determines which runtime environments can display exception and error details caught at the ErrorBoundary; acceptable values include: always, dev, and production
  • dangerouslyUseDynamicConfig: Dynamic config allows user to pass configUrl query string. This allows to load config without recompiling application. If the configUrl query string is passed, the worklist and modes will load from the referenced json rather than the default .env config. If there is no configUrl path provided, the default behaviour is used and there should not be any deviation from current user experience.
    Points to consider while using dangerouslyUseDynamicConfig:
    • User have to enable this feature by setting dangerouslyUseDynamicConfig.enabled:true. By default it is false.
    • Regex helps to avoid easy exploit. Default is /.*/. Setup your own regex to choose a specific source of configuration only.
    • System administrators can return cross-origin: same-origin with OHIF files to disallow any loading from other origin. It will block read access to resources loaded from a different origin to avoid potential attack vector.
    • Example config:
      js
      dangerouslyUseDynamicConfig: {
        enabled: false,
        regex: /.*/
      }

    Example 1, to allow numbers and letters in an absolute or sub-path only.
    regex: /(0-9A-Za-z.]+)(\/[0-9A-Za-z.]+)*/
    Example 2, to restricts to either hosptial.com or othersite.com.
    regex: /(https:\/\/hospital.com(\/[0-9A-Za-z.]+)*)|(https:\/\/othersite.com(\/[0-9A-Za-z.]+)*)/
    Example usage:
    http://localhost:3000/?configUrl=http://localhost:3000/config/example.json

  • onConfiguration: Currently only available for DicomWebDataSource, this option allows the interception of the data source configuration for dynamic values e.g. values coming from url params or query params. Here is an example of building the dicomweb datasource configuration object with values that are based on the route url params:
    text
    {
      namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
      sourceName: 'gcpdicomweb',
      configuration: {
        friendlyName: 'GCP DICOMWeb Server',
        name: 'gcpdicomweb',
        qidoSupportsIncludeField: false,
        imageRendering: 'wadors',
        thumbnailRendering: 'wadors',
        enableStudyLazyLoad: true,
        supportsFuzzyMatching: false,
        supportsWildcard: false,
        singlepart: 'bulkdata,video,pdf',
        onConfiguration: (dicomWebConfig, options) => {
          const { params } = options;
          const { project, location, dataset, dicomStore } = params;
          const pathUrl = `https://healthcare.googleapis.com/v1/projects/${project}/locations/${location}/datasets/${dataset}/dicomStores/${dicomStore}/dicomWeb`;
          return {
            ...dicomWebConfig,
            wadoRoot: pathUrl,
            qidoRoot: pathUrl,
            wadoUri: pathUrl,
            wadoUriRoot: pathUrl,
          };
        },
      },
    },

This configuration would allow the user to build a dicomweb configuration from a GCP healthcare api path e.g. http://localhost:3000/projects/your-gcp-project/locations/us-central1/datasets/your-dataset/dicomStores/your-dicom-store/study/1.3.6.1.4.1.1234.5.2.1.1234.1234.123123123123123123123123123123

:::note
You can stack multiple panel components on top of each other by providing an array of panel components in the rightPanels or leftPanels properties.

For instance we can use

text
rightPanels: [[dicomSeg.panel, tracked.measurements], [dicomSeg.panel, tracked.measurements]]

This will result in two panels, one with dicomSeg.panel and tracked.measurements and the other with dicomSeg.panel and tracked.measurements stacked on top of each other.

:::

Study Prefetcher

You can enable the study prefetcher so that OHIF loads the next/previous series/display sets
based on the proximity to the current series/display set. This can be useful to improve the user experience

js
studyPrefetcher: {
    /* Enable/disable study prefetching service (default: false) */
    enabled: true,
    /* Number of displaysets to be prefetched  (default: 2)*/
    displaySetsCount: 2,
    /**
     * Max number of concurrent prefetch requests (default: 10)
     * High numbers may impact on the time to load a new dropped series because
     * the browser will be busy with all prefetching requests. As soon as the
     * prefetch requests get fulfilled the new ones from the new dropped series
     * are sent to the server.
     *
     * TODO: abort all prefetch requests when a new series is loaded on a viewport.
     * (need to add support for `AbortController` on Cornerstone)
     * */
    maxNumPrefetchRequests: 10,
    /* Display sets loading order (closest (deafult), downward or upward) */
    order: 'closest',
  },

More on Accept Header Configuration

In the previous section we showed that you can modify the acceptHeader
configuration to request specific dicom transfer syntax. By default
we use acceptHeader: ['multipart/related; type=application/octet-stream; transfer-syntax=*'] for the following
reasons:

  • Ensures Optimal Transfer Syntax: By allowing the server to select the transfer syntax,
    the client is more likely to receive the image in a syntax that's well-suited for fast transmission
    and rendering. This might be the original syntax the image was stored in or another syntax that the server deems efficient.

  • Avoids Transcoding: Transcoding (converting from one transfer syntax to another) can be a resource-intensive process.
    Since the OHIF Viewer supports all transfer syntaxes, it is fine to accept any transfer syntax (transfer-syntax=*).
    This allows the server to send the images in their stored syntax, avoiding the need for costly on-the-fly conversions.
    This approach not only saves server resources but also reduces response times by leveraging the viewer's capability to handle various syntaxes directly.

  • Faster Data Transfer: Compressed transfer syntaxes generally result in smaller file sizes compared
    to uncompressed ones. Smaller files transmit faster over the network, leading to quicker load
    times for the end-user. By accepting any syntax, the client can take advantage of compression when available.

However, if you would like to get compressed data in a specific transfer syntax, you can modify the acceptHeader configuration or
requestTransferSyntaxUID configuration.

Data Source: stackRetrieveOptions

At the data source configuration level, you can set stackRetrieveOptions to customize Cornerstone stack image retrieval. Merged with defaults; only specify overrides. For example, set streaming: false when the data source returns uncompressed DICOM (e.g. application/octet-stream only) to avoid black image on load:

js
configuration: {
  acceptHeader: ['application/octet-stream'],
  stackRetrieveOptions: {
    retrieveOptions: { single: { streaming: false } },
  },
}

Environment Variables

We use environment variables at build and dev time to change the Viewer's
behavior. We can update the HTML_TEMPLATE to easily change which extensions
are registered, and specify a different APP_CONFIG to connect to an
alternative data source (or even specify different default hotkeys).

Environment Variable Description Default
HTML_TEMPLATE Which HTML template to use as our web app's entry point. Specific to PWA builds. index.html
PUBLIC_URL The route relative to the host that the app will be served from. Specific to PWA builds. /
APP_CONFIG Which configuration file to copy to output as app-config.js config/default.js
PROXY_TARGET When developing, proxy requests that match this pattern to PROXY_DOMAIN undefined
PROXY_DOMAIN When developing, proxy requests from PROXY_TARGET to PROXY_DOMAIN undefined
OHIF_PORT The port to run the webpack server on for PWA builds. 3000

You can also create a new config file and specify its path relative to the build
output's root by setting the APP_CONFIG environment variable. You can set the
value of this environment variable a few different ways:

After updating the configuration, yarn run build to generate updated build
output.


Platform Docs Docs Configuration Tours (`platform/docs/docs/configuration/tours.md`)


Configuring Tours in OHIF with Shepherd.js

In OHIF, you can configure guided tours for users by leveraging Shepherd.js, a JavaScript library for building feature tours. This page explains how you can define and customize these tours within your app configuration file.

Overview

Tours allow you to provide step-by-step guidance to users, explaining different features of your mode/extension or the viewer. Each tour is associated with a route and consists of several steps, each guiding the user through specific interactions in the viewer.

Adding a Tour to your Configuration

Here's how you can add a tour to your configuration file:

javascript
window.config = {
  customizationService: {
    'ohif.tours': {
      $set: [
        {
          id: 'basicViewerTour',
          route: '/viewer',
          steps: [
            {
              id: 'zoom',
              title: 'Zooming In and Out',
              text: 'You can zoom the images using the right click.',
              attachTo: {
                element: '.viewport-element',
                on: 'left',
              },
              advanceOn: {
                selector: '.cornerstone-viewport-element',
                event: 'CORNERSTONE_TOOLS_MOUSE_UP',
              },
            },
          ],
        },
      ],
    },
  },
};

Explanation of Parameters

`tours` Array

Each item in the tours array defines a specific tour for a particular route. The object contains the following properties:

  • id: A unique identifier for the tour. This helps in tracking whether the tour has been shown.
  • route: The route in the application where the tour is applicable. When the user navigates to this route, the tour can automatically trigger if it hasn't been shown before.
  • steps: An array of steps that define the individual guide elements in the tour. Each step corresponds to a UI element and guides the user through interactions.
  • tourOptions: An object that allows you to configure the overall behavior of the tour, such as using a modal overlay or defining default step options.

`steps` Array

Each step defines a part of the tour. Here's a breakdown of the properties you can define:

  • id: A unique identifier for the step within the tour.
  • title: The title of the step, which appears at the top of the tooltip for the step.
  • text: The content or description of the step, explaining what the user needs to do or understand.
  • attachTo: Specifies where the step should be attached in the DOM. It includes:
    • element: A string selector or a DOM element that the step should attach to.
    • on: Specifies the position of the tooltip relative to the element (e.g., 'top', 'left', 'bottom', 'right').
  • advanceOn: Defines an event that will automatically advance the tour to the next step. This is useful for actions like clicking a button or scrolling.
    • selector: The CSS selector for the element that triggers the advance.
    • event: The event name that advances the step, this can be a OHIF service event, or a cornerstone event, or any native JS event (e.g., 'click', 'CORNERSTONE_TOOLS_MOUSE_WHEEL').
  • beforeShowPromise: A function that returns a promise. When the promise resolves, the rest of the show logic for the step will execute. You can use this to ensure that the target element is ready before the step shows.

`tourOptions`

The tourOptions object allows you to configure the overall behavior of the tour. Here's a breakdown of the available properties:

  • useModalOverlay: A boolean that, if set to true, places the tour steps above a darkened modal overlay. The overlay creates an opening around the target element so it can remain interactive.
  • defaultStepOptions: Default options that apply to all steps in the tour. You can override these in individual steps. The following are some options available:
    • buttons: An array of button objects that appear in the footer of each step. Each button can trigger actions like advancing the tour or skipping it. For example:
      • text: The label text on the button.
      • action: A function to execute when the button is clicked. You can advance the tour using this.next(), or complete it using this.complete().
      • secondary: A boolean that, when set to true, styles the button as secondary (often for actions like skipping).

`floatingUIOptions`

You can define positioning options for the steps using Floating UI middleware. This helps control how the steps are positioned, especially near the browser edges.

For example, you can ensure that the steps maintain a margin of 24px from the viewport edges by configuring preventOverflow middleware:

javascript
floatingUIOptions: {
  middleware: [
    preventOverflow({ padding: 24 }),
    flip(), // Allows the step to flip if it is overflowing
  ]
}

Shepherd.js Lifecycle Events

Each step and tour can have lifecycle events like show, hide, complete, or cancel. These events allow you to hook into the tour’s lifecycle to perform actions when certain events are triggered.

For example:

javascript
when: {
  show() {
    console.log('Step shown!');
  },
  hide() {
    console.log('Step hidden.');
  }
}

Customizing Your Tour

Once you have a basic tour in place, you can extend it with more advanced features like custom scrolling behavior, dynamic elements, and event-based step advancement. For more details, check out the Shepherd.js documentation.

Licensing

All versions below 14.0 for Shepherd.JS is under the MIT license, if you wish to use any version above 14.0, you can visit the ShepherdJS website to learn about their pricing and plans Shepherd.js

LICENSE

Demo

Conclusion

By leveraging Shepherd.js, you can provide users with interactive and informative guided tours of the viewer. This can greatly improve the user experience and help users understand how to use key features.


Platform Docs Docs Configuration Ui (`platform/docs/docs/configuration/ui.md`)


UI & Appearance

OHIF's user interface is built on ui-next, a component library purpose-built
for medical imaging workflows. It provides a consistent set of React components,
a token-based theming system, a curated icon set, and a collection of UI services
that manage runtime behavior like modals, notifications, and viewport layout.

This page gives a high-level map of how these pieces fit together and where to
find detailed documentation for each.

Component Library

The component library is the foundation of every panel, toolbar, dialog, and
control in the viewer. Components are organized into three tiers:

  • Simple components — atomic building blocks like Button, Checkbox, Input,
    Label, Slider, and Switch. These are styled with the design system's tokens and
    are the smallest interactive units.

  • Compound components — composed from simple components to handle more
    complex interactions: Select, Dialog, DropdownMenu, Tabs, Table, Popover,
    Tooltip, Toast, and others. These manage their own state (open/close, selection,
    focus) via headless patterns.

  • OHIF-specific components — built for medical imaging workflows and not
    found in general-purpose libraries: AllInOneMenu, CinePlayer, DataRow,
    DataTable, Numeric, PanelSection, SmartScrollbar, ToolButton, and
    ToolButtonList. These integrate directly with OHIF's services and extension
    system.

Every component renders live in the interactive
Components section of this documentation site, where you
can see props, variants, and copy usage examples.

Appearance Dialog

The Appearance dialog is an optional UI that lets end users switch presets,
apply custom CSS overrides, and share themes via URL. It is not enabled by
default, but deployers can
opt in via configuration.
See Appearance & Theming
for the full setup and developer guide.

Colors & Theming

OHIF uses a token-based color system built on CSS custom properties with HSL
values. The base theme (dark mode) is defined in :root via Tailwind CSS, and
theme presets override specific tokens by applying a CSS class to document.body.

The theming system covers:

  • Design tokens — a set of semantic color variables (--background,
    --primary, --card, --border, etc.) that every component references. Tokens
    are defined as HSL triplets and consumed via Tailwind's hsl(var(...)) pattern.

  • Theme presets — six built-in themes (three tonal, three neutral) that shift
    the entire interface's color palette. Presets are defined as JSON files and
    applied via CSS classes. Also see:
    Creating Themes and
    Adding a Theme Preset.

  • Accessibility — foreground tokens are paired with every surface token to
    maintain contrast ratios across themes. When adding custom themes,
    test colors to match accessibility standards.

Explore the live token swatches and theme picker in the interactive
Colors & Theming page, and see
Appearance & Theming
for the full configuration and developer guide.

Iconography

OHIF ships a curated set of icons designed specifically for medical imaging interfaces.
Icons are SVG-based, registered via addIcon(), and rendered through the Icons
component. They follow the same token system as the rest of the UI, so icon colors
respond to the active theme.

Browse the full set with search and click-to-copy in the
Iconography page.

White Labeling

OHIF supports replacing the header logo with custom branding via the
whiteLabeling configuration key. This lets you rebrand the viewer without
modifying source code.

Add a whiteLabeling entry to your configuration file with a
createLogoComponentFn that returns a React element:

js
window.config = {
  /** .. **/
  whiteLabeling: {
    createLogoComponentFn: function(React) {
      return React.createElement(
        'a',
        {
          target: '_self',
          rel: 'noopener noreferrer',
          className: 'text-purple-600 line-through',
          href: '/',
        },
        React.createElement('img', {
          src: './customLogo.svg',
        })
      );
    },
  },
  /** .. **/
};

You can use Tailwind CSS utility classes in the className property to style
your custom logo component.

UI Services

While the component library handles what gets rendered, UI services handle
the runtime behavior: opening modals, showing notifications, managing viewport
layout, and coordinating dialogs. These services use a pub/sub architecture and
are accessed through the servicesManager:

Service What it manages
Modal Service Full-screen and contained modals (including the Appearance dialog)
Dialog Service Lightweight dialogs with form inputs and confirmations
Notification Service Toast notifications (success, warning, error, info)
Viewport Grid Service Viewport layout, grid arrangement, and active viewport tracking
Viewport Dialog Service Dialogs anchored to specific viewports
Viewport Action Menu Context menus and action buttons on viewport corners
Cine Service Cine playback controls and frame rate

UI services are documented in the Services > UI
section.

Customization Service

The Customization Service
is the mechanism that ties everything together. It allows deployers and
extension authors to override, extend, or replace UI components and behaviors
without modifying core code. Customizations can be scoped to a specific mode, set
globally via configuration, or provided as defaults by extensions.

The Appearance dialog itself is delivered as a customization module. Deployers
enable it by adding a single reference to their config's customizationService
array. This pattern means that any part of the UI that supports customization
can be configured the same way.

See the full customization guide at
Customization Service,
including the syntax reference for $set, $push, $merge, $filter, and
other operations.


Platform Docs Docs Configuration Url (`platform/docs/docs/configuration/url.md`)


URL

You can modify the URL at any state of the app to get the desired result. Here
are different part of the APP that you can modify:

WorkList

The WorkList can be modified by adding the following query parameters:

PatientName

The patient name can be modified by adding the PatientName query parameter.

js
/?patientName=myQuery

MRN

The MRN can be modified by adding the MRN query parameter.

js
/?mrn=myQuery

Description

The description can be modified by adding the Description query parameter.

js
/?description=myQuery

Modality

The modality can be modified by adding the modalities query parameter.

js
/?modalities=MG

Accession Number

The accession number can be modified by adding the accession query parameter.

js
/?accession=myQuery

DataSources

If you happen to have multiple data sources configured, you can filter the
WorkList by adding the dataSources query parameter.

js
/?dataSources=orthanc

Note1: You should pass the sourceName of the data source in the configuration file (not the friendly name nor the name)
Note2: Make sure that the configuration file you are using actually includes that data source. You cannot use a data source from another configuration file.

:::tip

You can add sortBy and sortDirection query parameters to sort the WorkList

js
/?patientName=myquery&sortBy=studyDate&sortDirection=ascending

:::

Viewer

The Viewer can be modified by adding the following query parameters:

Mode

As you have seen before, the Viewer can be configured to be in different modes.
Each mode registers their id in the URL.

For instance

js
/viewer?StudyInstanceUIDs=1.3.6.1.4.1.14519.5.2.1.7009.2403.871108593056125491804754960339

will open the viewer in the basic (longitudinal) mode with the StudyInstanceUID
1.3.6.1.4.1.14519.5.2.1.7009.2403.871108593056125491804754960339.

And if configured, the same study can be opened in the tmtv mode

js
/tmtv?StudyInstanceUIDs=1.3.6.1.4.1.14519.5.2.1.7009.2403.871108593056125491804754960339

StudyInstanceUIDs

You can open more than one study in the Viewer by adding the StudyInstanceUIDs

js
/viewer?StudyInstanceUIDs=1.3.6.1.4.1.25403.345050719074.3824.20170125095722.1&StudyInstanceUIDs=1.3.6.1.4.1.25403.345050719074.3824.20170125095258.1

:::tip

You can use this feature to open a current and prior study in the Viewer.
Read more in the Hanging Protocol Module section. You can also use commas to separate
values.

:::

SeriesInstanceUIDs

Sometimes you need to only retrieve a specific series in a study, you can do
that by providing series level QIDO query parameters in the URL such as
SeriesInstanceUIDs. This does NOT work with instance or study
level parameters. For example:

js
http://localhost:3000/viewer?StudyInstanceUIDs=1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5&SeriesInstanceUIDs=1.3.6.1.4.1.25403.345050719074.3824.20170125095449.8

This will only open the viewer with one series (one displaySet) loaded, and no
queries made for any other series.

Sometimes you need to only retrieve a subset of series in a study, you can do
that by providing more than one series, separated by commas. For example:

js
http://localhost:3000/viewer?StudyInstanceUIDs=1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5&SeriesInstanceUIDs=1.3.6.1.4.1.25403.345050719074.3824.20170125095449.8,1.3.6.1.4.1.25403.345050719074.3824.20170125095506.10

This will only open the viewer with two series (two displaySets) loaded, and no
queries made for any other series.

initialSeriesInstanceUID

Alternatively, sometimes you want to just open the study on a specified series, but allowing other
series to be present too. This is the same behavior can be
achieved by using the initialSeriesInstanceUID parameter. For example:

js
http://localhost:3000/viewer?StudyInstanceUIDs=1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5&initialSeriesInstanceUID=1.3.6.1.4.1.25403.345050719074.3824.20170125095449.8

This will open all the series in the study, but the viewer will start with the
series specified by the initialSeriesInstanceUID parameter.

Note that you can combine these, if you want to load a specific set of series
plus show an initial one as the first one selected, for example:

js
http://localhost:3000/viewer?StudyInstanceUIDs=1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5&SeriesInstanceUIDs=1.3.6.1.4.1.25403.345050719074.3824.20170125095449.8,1.3.6.1.4.1.25403.345050719074.3824.20170125095506.10&initialSeriesInstanceUID=1.3.6.1.4.1.25403.345050719074.3824.20170125095506.10

initialSopInstanceUID

You can also specify the initial SOP Instance to be displayed by using the
initialSopInstanceUID parameter. For example:

js
http://localhost:3000/viewer?StudyInstanceUIDs=1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5&SeriesInstanceUIDs=1.3.6.1.4.1.25403.345050719074.3824.20170125095449.8&initialSopInstanceUID=1.3.6.1.4.1.25403.345050719074.3824.20170125095501.9

This will open the study with the filtered series, and navigate to the slice 101
which happens to be the SOP Instance specified by the initialSopInstanceUID

Note: again you can mix and match

js
http://localhost:3000/viewer?StudyInstanceUIDs=1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5&SeriesInstanceUIDs=1.3.6.1.4.1.25403.345050719074.3824.20170125095449.8,1.3.6.1.4.1.25403.345050719074.3824.20170125095506.10&initialSeriesInstanceUID=1.3.6.1.4.1.25403.345050719074.3824.20170125095506.10&initialSopInstanceUID=1.3.6.1.4.1.25403.345050719074.3824.20170125095510.8

You can even load the whole study and only specify the initial SOP Instance to be displayed. Although
it will take more time to match, but it works as expected.

js
http://localhost:3000/viewer?StudyInstanceUIDs=1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5&initialSopInstanceUID=1.3.6.1.4.1.25403.345050719074.3824.20170125095510.8

hangingProtocolId

You can select the initial hanging protocol to apply by using the
hangingProtocolId parameter. The selected parameter must be available in a
hangingProtocolModule registration, but does not have to be active.

For instance for loading a specific study in mpr mode from start you can use:

js
http://localhost:3000/viewer?StudyInstanceUIDs=1.3.6.1.4.1.25403.345050719074.3824.20170125095438.5&hangingProtocolId=@ohif/mnGrid

token

Although not recommended, you can use the token param in the URL which will inject
the token into the Authorization header of the request.


Platform Docs Docs Deployment Authorization (`platform/docs/docs/deployment/authorization.md`)


Authorization and Authentication

The OHIF Viewer can be configured to work with authorization servers that support one or more of the OpenID-Connect authorization flows. The Viewer finds it's OpenID-Connect settings on the oidc configuration key. You can set these values in your configuration files. For instance you can take a look at our
google.js configuration file.

js
oidc: [
  {
    // ~ REQUIRED
    authority: 'https://accounts.google.com',
    client_id: '723928408739-k9k9r3i44j32rhu69vlnibipmmk9i57p.apps.googleusercontent.com',
    redirect_uri: '/callback',
    response_type: 'id_token token',
    scope: 'email profile openid https://www.googleapis.com/auth/cloudplatformprojects.readonly https://www.googleapis.com/auth/cloud-healthcare', // email profile openid
    // ~ OPTIONAL
    post_logout_redirect_uri: '/logout-redirect.html',
    revoke_uri: 'https://accounts.google.com/o/oauth2/revoke?token=',
    automaticSilentRenew: true,
    revokeAccessTokenOnSignout: true,
  },
],

You need to provide the following information:

  • authority: The URL of the authorization server.
  • client_id: The client id of your application (provided by the authorization server).
  • redirect_uri: The callback URL of your application.
  • response_type: The response type of the authorization flow (e.g. id_token token, learn more about different flows).
  • scope: The scopes that your application needs to access
  • post_logout_redirect_uri: The URL that the user will be redirected to after logout.
  • revoke_uri: The URL that the user will be redirected to after logout.
  • automaticSilentRenew: If true, the user will be automatically logged in after the token expires.
  • revokeAccessTokenOnSignout: If true, the access token will be revoked on logout.

How it works

The Viewer uses the userAuthenticationService to set the OpenID-Connect settings. The userAuthenticationService is a singleton service that is responsible for authentication and authorization. It is initialized by the app and you can grab it
from the servicesManager

js
const userAuthenticationService = servicesManager.services.userAuthenticationService;

Then the userAuthenticationService will inject the token as Authorization header in the requests that are sent to the server (both metadata
and pixelData).

Token based authentication in URL

Sometimes (although not recommended), some servers like to send the token
in the query string. In this case, the viewer will automatically grab the token from the query string
and add it to the userAuthenticationService and remove it from the query string (to prevent it from being logged in the console
in future requests).

and example would be

js
http://localhost:3000/viewer?StudyInstanceUIDs=1.2.3.4.5.6.6.7&token=e123125jsdfahsdf

Securing dynamic datasource URLs

When using dicomwebproxy or dicomjson data sources with a runtime ?url=... query parameter,
configure explicit trust boundaries to prevent credential exfiltration.

Use these datasource configuration options:

  • dangerouslyAllowedOriginsForAuthenticatedEnvironments: Origin allowlist used only when the viewer is running in an authenticated environment. Entries may use http:// or https:// and can include localhost origins.

Allowed entry format for dangerouslyAllowedOriginsForAuthenticatedEnvironments:

  • Must be a bare origin only: scheme://host[:port]
  • http:// and https:// are both allowed
  • Localhost is allowed when explicitly listed (for example, http://localhost:5000)
  • Must not include username/password, path, query string, or hash
  • Invalid entries are ignored and logged as misconfigured

Policy summary:

  • In unauthenticated environments, any HTTP(S) ?url= origin is allowed.
  • In authenticated environments, same-origin ?url= values are allowed by default.
  • In authenticated environments, cross-origin ?url= values must be present in dangerouslyAllowedOriginsForAuthenticatedEnvironments, otherwise loading fails closed.
  • In unauthenticated environments, cross-origin config URLs are fetched with:
    • method: 'GET'
    • mode: 'cors'
    • credentials: 'omit'
    • redirect: 'error'
    • referrerPolicy: 'no-referrer'
  • In unauthenticated environments, same-origin config URLs use a plain fetch() call (browser default credentials: 'same-origin').
  • Same-origin config URLs are fetched using simple fetch behavior (so same-origin session/cookie auth is preserved).
  • In authenticated environments, allowlisted cross-origin config URLs are fetched using simple fetch behavior.
  • Returned datasource configuration payloads are consumed as-is (no additional URL/config scrubbing).

Example:

js
dataSources: [
  {
    namespace: '@ohif/extension-default.dataSourcesModule.dicomwebproxy',
    sourceName: 'dicomwebproxy',
    configuration: {
      name: 'dicomwebproxy',
      dangerouslyAllowedOriginsForAuthenticatedEnvironments: [
        'https://config.example.com',
        'http://localhost:5000',
      ],
    },
  },
]

Implicit Flow vs Authorization Code Flow

The Viewer supports both the Implicit Flow and the Authorization Code Flow. The Implicit Flow is the default currently, as it is easier to set up and use. However, you can opt for better security by using the Authorization Code Flow. To do so, add useAuthorizationCodeFlow to the configuration and change the response_type from id_token token to code.

Read more about Implicit Flow vs Authorization Code Flow here and here

js
oidc: [
  {
    authority: 'https://accounts.google.com',
    client_id: '723928408739-k9k9r3i44j32rhu69vlnibipmmk9i57p.apps.googleusercontent.com',
    redirect_uri: '/callback',
    scope: 'email profile openid',
    post_logout_redirect_uri: '/logout-redirect.html',
    revoke_uri: 'https://accounts.google.com/o/oauth2/revoke?token=',
    revokeAccessTokenOnSignout: true,
    automaticSilentRenew: true,
    // CHANGE THESE *****************************
    response_type: 'code',
    useAuthorizationCodeFlow: true,
  },
],

In fact, since browsers are blocking third-party cookies, the Implicit Flow will cease functioning in the future (not specific to OHIF). Read more here. It is recommended to use the Authorization Code Flow and begin migrating to it.

:::note
For the Authorization Code Flow, when authenticating against Google, you must add the client_secret to the configuration as well. Unfortunately, this seems to occur only with Google.
:::


Platform Docs Docs Deployment Azure (`platform/docs/docs/deployment/azure.md`)


Microsoft Azure

This guide explains how to configure a DICOM datasource in OHIF using Azure Healthcare APIs. It focuses on the configuration details and parameters necessary for integration.


Configuring Azure Healthcare APIs as a DICOMweb Data Source

Follow these steps to set up Azure as a DICOM datasource for the OHIF Viewer.


Azure AD Registration:

  1. Navigate to the Azure Portal.
  2. Select "Azure Active Directory" > "App registrations" > "New registration".
  3. Name your application.
  4. Under "Supported account types", select "Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)".
  5. Enter the following values in your redirect URI tab:

API Permissions:

  1. Under your registered application, go to "API permissions".
  2. Click "Add a permission".
  3. Choose the Azure API for DICOM (Dicom.ReadWrite). If you can't find it, refer to the "Configure Azure DICOMWEB Service" section and then return to this step.

Authentication:

  1. Under "Authentication", check the "ID tokens" box since we are using OpenID Connect.

App Client ID and Tenant ID:

  1. Copy your app client ID and tenant ID to prepare for use in configuring an OHIF datasource.

  1. The first time a user logs in, they will be prompted to consent to the permissions your application has requested.
  2. Once they grant consent, your application can use the obtained access token to call the specific Microsoft API on behalf of the user.

Configure Azure DICOMWEB Service:

  1. Create a Health Data Services workspace:

  2. Visit the newly created workspace and press "Deploy DICOM Service":

  3. After the DICOM service is deployed, visit the "CORS headers" section:

  4. Set the headers and origins to * and specify the HTTP methods you'd like to use:

  5. Save the changes.

  6. Add the Microsoft emails of the users you'd like to grant access to your DICOM service in the "Access control" section and assign them the "DICOM Data Owner" role (or other roles depending on your requirements):

  7. Copy your DICOM service URL to prepare it for usage in OHIF as a datasource:

  8. Upload your DICOM files to your service.


1. Configure OIDC Authentication

Azure uses OpenID Connect (OIDC) for authentication. Update the OIDC section in your configuration file with the following parameters:

json
"oidc": [
  {
    "redirect_uri": "/callback",
    "response_type": "id_token token",
    "scope": "openid https://dicom.healthcareapis.azure.com/Dicom.ReadWrite",
    "post_logout_redirect_uri": "/logout-redirect.html",
    "automaticSilentRenew": false,
    "revokeAccessTokenOnSignout": true,
    "loadUserInfo": false,
    "authority": "https://login.microsoftonline.com/{tenant-id}/v2.0/",
    "client_id": "{client-id}"
  }
]

Parameters:

  • redirect_uri: The URL where users are redirected after successful authentication.
  • response_type: Specifies the authentication response type (id_token and token).
  • scope: Defines the level of access. Use Dicom.ReadWrite to allow read and write access to DICOM data.
  • post_logout_redirect_uri: The URL users are redirected to after logout.
  • automaticSilentRenew: Automatically renews tokens without user interaction. Set to false for manual renewal.
  • revokeAccessTokenOnSignout: Revokes access tokens upon logout for added security.
  • loadUserInfo: Disables loading additional user information; set to false for Azure as it is not supported.
  • authority: The Azure AD tenant URL for OIDC authorization.
  • client_id: The application’s client ID from Azure AD.

2. Add the Data Source Configuration

Update the data source configuration file with your Azure Healthcare APIs details:

json
{
  "namespace": "@ohif/extension-default.dataSourcesModule.dicomweb",
  "sourceName": "ohif_azure",
  "friendlyName": "ohif_azure",
  "configuration": {
    "singlepart": "bulkdata,pdf,video",
    "imageRendering": "wadors",
    "thumbnailRendering": "wadors",
    "supportsWildcard": true,
    "enableStudyLazyLoad": true,
    "supportsFuzzyMatching": false,
    "supportsStow": true,
    "qidoRoot": "https://{your-dicom-instance}.dicom.azurehealthcareapis.com/v2",
    "wadoUriRoot": "https://{your-dicom-instance}.dicom.azurehealthcareapis.com/v2",
    "wadoRoot": "https://{your-dicom-instance}.dicom.azurehealthcareapis.com/v2"
  }
}

Parameters:

  • qidoRoot: Base URL for QIDO-RS queries.
  • wadoUriRoot: Base URL for WADO-URI requests.
  • wadoRoot: Base URL for WADO-RS requests.

3. Running the Viewer with Azure Configuration

  1. Save the above configurations in your OHIF Viewer configuration file.

  2. Run the viewer:

    bash
    cd OHIFViewer
    yarn install --frozen-lockfile
    APP_CONFIG=config/azure.js yarn run dev

    Replace config/azure.js with the path to your configuration file.


Additional Notes

  • Ensure that the Azure Healthcare API is enabled for your subscription and that the necessary permissions (e.g., Dicom.ReadWrite) are assigned to the OIDC client.
  • The qidoRoot, wadoUriRoot, and wadoRoot should point to your Azure DICOM service URL. Replace {your-dicom-instance} with your actual instance name.

This setup allows OHIF to interact seamlessly with Azure's Healthcare APIs, enabling robust DICOM management and visualization.


Platform Docs Docs Deployment Build For Production (`platform/docs/docs/deployment/build-for-production.md`)


Build for Production

Build Machine Requirements

Getting the Code

With Git:

bash
# Clone the remote repository to your local machine
git clone https://github.com/OHIF/Viewers.git

More on: git clone,
git checkout

From .zip:

OHIF/Viewers: master.zip

Restore Dependencies & Build

Open your terminal, and navigate to the directory containing the source files.
Next run these commands:

bash
# If you haven't already, enable yarn workspaces
yarn config set workspaces-experimental true

# Restore dependencies
yarn install --frozen-lockfile

# Build source code for production
yarn run build

If everything worked as expected, you should have a new dist/ directory in the
platform/app/dist folder. It should roughly resemble the following:

bash title="platform/app/dist/"
platform/app/dist/"">├── app-config.js
├── app.bundle.js
├── app.css
├── index.html
├── manifest.json
├── service-worker.js
└── ...

By default, the build output will connect to OHIF's publicly accessible PACS. If
this is your first time setting up the OHIF Viewer, it is recommended that you
test with these default settings. After testing, you can find instructions on
how to configure the project for your own imaging archive below.

Configuration

The configuration for our viewer is in the <root>platform/app/public/config
directory. Our build process knows which configuration file to use based on the
APP_CONFIG environment variable. By default, its value is
config/default.js. The majority of the viewer's features,
and registered extension's features, are configured using this file.

The easiest way to apply your own configuration is to modify the default.js
file. For more advanced configuration options, check out our
configuration essentials guide.

Next Steps

Deploying Build Output

Drag-n-drop

Easy

Advanced

Testing Build Output Locally

A quick way to test your build output locally is to spin up a small webserver.
You can do this by running the following commands in the dist/ output
directory:

bash
# Install http-server as a globally available package
yarn global add http-server

# Change the directory to the platform/app
cd platform/app

# Serve the files in our current directory
npx serve ./dist -c ../public/serve.json

Automating Builds and Deployments

If you found setting up your environment and running all of these steps to be a
bit tedious, then you are in good company. Thankfully, there are a large number
of tools available to assist with automating tasks like building and deploying
web application. For a starting point, check out this repository's own use of:


Platform Docs Docs Deployment Cors (`platform/docs/docs/deployment/cors.md`)


Cross-Origin Information for OHIF

This document describes various security configurations, settings and environments/contexts needed to fully leverage OHIF’s capabilities. One may need some configurations while others might need ALL of them - it all depends on the environment OHIF is expected to run in.

In particular, three of OHIF’s features depend on these configurations:

Embedding OHIF in an iframe

As described here, there are cases where OHIF will be embedded in an iframe. The following links provide more information for setting up and configuring OHIF to work in an iframe:

Secure Context

MDN defines a secure context as “a Window or Worker for which certain minimum standards of authentication and confidentiality are met.“

Any local URL is considered secure. The following are some examples of local URLs that are considered secure…

URLs that are NOT local must be delivered over https:// or wss:// (i.e. TLS) to be considered secure. See When is a context considered secure in MDN for more information.

iframes

A page embedded in an iframe is considered secure if it itself and every one of its embedding ancestors are delivered securely. Otherwise it is deemed insecure.

Configuring/setting up a secure context

Local URLs are considered secure, and as such whenever OHIF is accessed via a local URL (e.g. http://localhost:3000) it is running in a secure context. For example, in a development environment using the default webpack setup, OHIF can be deployed and accessed in a secure context at http://localhost:3000.

The best alternative is to host OHIF over HTTPS.

:::tip
OHIF can be served over HTTPS in a variety of ways (these are just some examples).

  • Website hosting services that offer HTTPS deployment (e.g,. Netlify) or offer HTTPS load balancers (AWS, Google Cloud etc.)
  • Setting up a reverse proxy (e.g. nginx) with a self-signed certificate that forwards requests to the OHIF server

Origin Definition

According to MDN, a Web content’s origin is defined by the scheme (protocol), hostname (domain), and port of the URL used to access it. Two objects have the same origin only when the scheme, hostname, and port all match.

CORS - Cross-Origin Resource Sharing

A cross-origin resource is a resource (e.g. image, JSON, etc) that is served by one origin and used/referenced by a different origin.

CORS is the protocol utilized by web servers and browsers whereby a server of one origin identifies and/or restricts which of its resources that other origins (i.e. other than its own) a browser should allow access to. By default a browser does not permit cross-origin resource sharing.

The CORS mechanism relies on the HTTP response headers from the server to indicate if a resource can be shared with a different origin.

See the MDN CORS article for more information.

CORS HTTP Headers

The header that mostly concerns OHIF is listed below and should be configured accordingly on the DICOMweb server or any data source that OHIF would make XMLHttpRequests to for its data.

http
Access-Control-Allow-Origin: `<origin>` | *

:::tip
The Access-Control-Allow-Origin header specifies which origins can access the served resource embedded in the response.

Either a single, specific origin (i.e. <origin>) can be specified or ALL origins (i.e. *)

See MDN for more information.
:::

CORS in OHIF

OHIF fetches and displays data and images from data sources. It invokes XMLHttpRequests to some data sources such as DICOMweb data sources to fetch the information to render. Typically, a DICOMweb server is hosted on a completely different origin than the one serving OHIF. As such, those XMLHttpRequests use CORS.

Troubleshooting CORS in OHIF

The following is an example screenshot of the browser console when one of OHIF’s DICOMweb data source servers is not configured for CORS.

And the following is what is in the accompanying network tab.

:::info
Setting the appropriate CORS header varies per server or service that is hosting the data source. What follows below is just one example to remedy the problem.
:::

:::tip
If Orthanc is the data source running in a Docker container composed with/behind nginx. And OHIF is being served at localhost:3000. The issue can be remedied by adding either of the following to Orthanc’s Docker container nginx.conf file.

nginx
add_header 'Access-Control-Allow-Origin' 'http://localhost:3000' always;

Or

nginx
add_header 'Access-Control-Allow-Origin' '*' always;

:::

Header Values (see [MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cross-Origin_Resource_Policy#usage) for more information)

Value Description
same-site Only requests from the same site can read the resource.
same-origin Only requests from the same origin can read the resource.
cross-origin Requests from any origin can read the resource. The value is useful and exists primarily for letting documents with the COEP require-corp value know that the resource is ok to be embedded

OHIF and CORP

PDF from a Cross Origin DICOMweb Data Source

There are some DICOMweb data sources (e.g. dcm4chee) whereby OHIF uses the data source’s /rendered endpoint to embed a DICOM PDF document in the OHIF DOM using an <object> tag.

As specified for the COEP require-corp value, a page like OHIF with COEP header require-corp can embed cross-origin resources in DOM elements that have the crossorigin attribute OR the resource is delivered with an appropriate CORP header. The <object> tag does NOT support the crossorigin attribute. As such, the PDF must be delivered with a CORP header.

:::tip
Setting the CORP header varies per server or service that is hosting the data source. The following is just one example.

For a dcm4chee DICOMweb data source composed in Docker behind nginx, the CORP header can be configured in the nginx.conf file as such:

nginx
add_header 'Cross-Origin-Resource-Policy' 'cross-origin' always;

If the dcm4chee server and the OHIF server are hosted on the same site, then the following would also work:

nginx
add_header 'Cross-Origin-Resource-Policy' 'same-site' always;

:::


Platform Docs Docs Deployment Custom Url Access (`platform/docs/docs/deployment/custom-url-access.md`)


Hosting the Web Viewer on a Custom URL Path

You can host the viewer on a subpath like /abc instead of the root /. There are two levels of customization depending on how you want to serve your static assets.

If you want to make the viewer accessible from a custom path (e.g. /abc) and don’t care where the assets are loaded from (they’ll be fetched from the root /), this setup is for you.

What You Get

  • Viewer available at https://yourdomain.com/abc
  • All assets (JS, WASM, etc.) still loaded from the root (/app.js, /viewer.wasm, etc.)

How To Set It Up

  1. Set routerBasename in your config file (e.g., config/myConfig.js) to /abc
  2. Build the viewer with:
bash
APP_CONFIG=config/myConfig.js yarn build

Local Development

bash
APP_CONFIG=config/myConfig.js yarn dev

Advanced Setup (Custom Asset Path)

If you want to host the viewer at /abc and serve static assets from a different location (e.g. /my-private-assets), this is a more advanced scenario.

What You Get

  • Viewer accessible from https://yourdomain.com/abc
  • All assets loaded from https://yourdomain.com/my-private-assets/

Why This is Tricky

Some libraries (especially ones using WASM) load assets using relative paths, which can break if not handled carefully. To solve this:

  • Set routerBasename to /abc
  • Set PUBLIC_URL to /my-private-assets/
  • Webpack will load assets from the specified public URL.

Local Development Notes

In development, use proxy rewrites to handle relative asset paths. Example for dicom-microscopy-viewer:

js
proxy: {
  '/dicom-microscopy-viewer': {
    target: 'http://localhost:3000',
    pathRewrite: {
      '^/dicom-microscopy-viewer': `/${PUBLIC_URL}/dicom-microscopy-viewer`,
    },
  },
}

This ensures local development can find assets even when libraries expect them at certain paths.

Building and Serving in Production

To build the viewer for production:

bash
PUBLIC_URL=/my-private-assets/ APP_CONFIG=config/myConfig.js yarn build

If you're using npx serve, make sure to update serve.json:

json
{
  "rewrites": [{ "source": "*", "destination": "/abc/index.html" }]
}

Serve the viewer like this:

bash
cd platform/app
mv dist abc  # Rename dist folder to match your viewer route
npx serve -c ./public/serve.json

🐳 Using Docker? You're Covered

If you’re using our Dockerfile, you’re all set — it already handles copying specific asset folders (like dicom-microscopy-viewer) to the root:

dockerfile
COPY --from=builder /usr/src/app/platform/app/dist/dicom-microscopy-viewer /usr/share/nginx/html/dicom-microscopy-viewer

Keep an eye on the browser network tab for any assets that might fail to load — if any other libraries require similar treatment, you’ll need to handle those as well.


Summary

Goal routerBasename PUBLIC_URL Assets Load From
Viewer at /abc, assets from / /abc default Root /
Viewer at /abc, assets from /my-private-assets /abc /my-private-assets/ /my-private-assets/

Platform Docs Docs Deployment Google Cloud Healthcare (`platform/docs/docs/deployment/google-cloud-healthcare.md`)


Google Cloud Healthcare

The Google Cloud Healthcare API is a
powerful option for storing medical imaging data in the cloud.

An alternative to deploying your own PACS is to use a software-as-a-service
provider such as Google Cloud. The Cloud Healthcare API promises to be a
scalable, secure, cost effective image storage solution for those willing to
store their data in the cloud. It offers an
almost-entirely complete DICOMWeb API
which requires tokens generated via the
OAuth 2.0 Sign In flow.
Images can even be transcoded on the fly if this is desired.

Setup a Google Cloud Healthcare Project

  1. Create a Google Cloud account

  2. Create a project in Google Cloud

    A project in Google Cloud can be created by clicking the projects drop down box.

    And then clicking the NEW PROJECT button in the top-right corner of the
    dialogue that is displayed.

  3. Enable the Cloud Healthcare API for your project

    :::tip
    An API can be enabled through the APIs & Services > Enabled APIs & Services
    console and clicking the + ENABLE APIS AND SERVICES button.

    :::

    :::tip
    The principal (i.e. account) that is enabling the Cloud Healthcare API will require
    the following roles that can be set in the IAM & Admin > IAM console for the
    desired project.

    • Service Usage Viewer
    • Service Usage Admin
      :::

    :::tip
    Roles can be added to a principal in the IAM & Admin > IAM console by clicking
    the Edit principal (i.e. pencil) icon to the right of a principal or by clicking the
    GRANT ACCESS button at the top of the list of principals. The GRANT ACCESS
    button is particularly useful if the Edit principal icon is disabled.
    :::

  4. (Optional): Create a Dataset and DICOM Data Store for storing your DICOM data

    :::tip
    To both list existing datasets as well as create a new dataset for your project,
    the principal (i.e. account) must have the following roles enabled
    in the IAM & Admin > IAM console.

    • Editor

    :::

  5. Enable the Cloud Resource Manager API for your project.

    Note: If you are having trouble finding the APIs, use the search box at
    the top of the Cloud console.

  6. Go to APIs & Services > OAuth Consent Screen to create an OAuth Consent screen and fill in your application details.

    • Run through the three step process of adding an OAuth Consent Screen, clicking SAVE AND CONTINUE at the end of each step.

    • For the Scopes step, for Google APIs, click the ADD OR REMOVE SCOPES button.

    • In the Update selected scopes dialogue that flies in from the right, add the
      following scopes to the Manually add scopes text box.

      • https://www.googleapis.com/auth/cloudplatformprojects.readonly
      • https://www.googleapis.com/auth/cloud-healthcare
    • Click ADD TO TABLE and then click UPDATE

  7. Go to APIs & Services > Credentials to create a new set of credentials:

    • Click + CREATE CREDENTIALS and from the drop down select OAuth Client ID.
      See OAuth 2.0 Client ID for more information.

    • Choose the "Web Application" type

    • Add your domain (e.g. http://localhost:3000) to the Authorized JavaScript
      origins.

    • Add your domain, plus callback (e.g. http://localhost:3000/callback) to the Authorized Redirect URIs.

    • Save your Client ID for later.

  8. (Optional): Create a bucket containing DICOM files and import it into a Data Store

    • When importing a bucket into a Data Store, the following warning might be
      displayed indicating that the Cloud Healthcare Service Agent service account associated with the
      project does not have the Storage Object Viewer role.

    • The Cloud Healthcare Service Agent service account can be displayed in the
      IAM & Admin > IAM console by checking the Include Google-provided role grants checkbox.
      The Storage Object Viewer role can then be granted to the Cloud Healthcare Service Agent service account.

    • More information regarding the Cloud Healthcare Service Agent service account can
      be found at https://cloud.google.com/healthcare-api/docs/permissions-healthcare-api-gcp-products

  9. (Optional): Enable Public Datasets that are being hosted by Google:
    https://cloud.google.com/healthcare/docs/resources/public-datasets/

Run the viewer with your OAuth Client ID

  1. Open the config/google.js file and change YOURCLIENTID to your Client ID
    value.
  2. Run the OHIF Viewer using the config/google.js configuration file
bash
cd OHIFViewer
yarn install --frozen-lockfile
APP_CONFIG=config/google.js yarn run dev

Configuring Google Cloud Healthcare as a datasource in OHIF

A Google Cloud Healthcare DICOM store can be configured as a DICOMweb datasource
in OHIF. A full or partial path is permitted in the configuration file. For
partial paths, the data source configuration UI
will assist in filling in the missing pieces. For example, a configuration with
empty wadoUriRoot, qidoRoot and wadoRoot will prompt for the entire path
step-by-step starting with the project.


Platform Docs Docs Deployment Iframe (`platform/docs/docs/deployment/iframe.md`)


iframe

With the transition to more advanced visualization, loading, and rendering techniques using WebWorkers, WASM, and WebGL, the script tag usage of the OHIF viewer v3 has been deprecated.
An alternative option for script tag usage is to employ an iframe. You can utilize the iframe element to load the OHIF viewer and establish communication with it using the postMessage API if needed.

We recommend utilizing modern development practices and incorporating OHIF viewer within your application using a more modular and integrated approach, such as leveraging bundlers, other UI
components, and frameworks.

Static Build

You can use the iframe element to load the OHIF viewer as a child element of your application if you need the
viewer to be embedded within your application. The iframe element can be used as follows (use your own custom styles)

html
<iframe src="./path-to-ohif-build" style="width: 100%; height: 500px; border: none"/>

The important thing to note here is that the iframe element is loading the OHIF viewer from the ./path-to-ohif-build. This path can be
named anything you want, but it should be the path to the OHIF viewer build directory. The build directory is the directory that
contains the index.html file (See build for production for more information).

It is also required that the PUBLIC_URL environment variable is set to the same path. For example, if the iframe is
`` (which means there is a ohif folder containing the build in your main app), then you need to:

  1. use a config (e.g. config/myConfig.js) file that is using the routerBasename of /ohif (note the one / - it is not /ohif/).
  2. build the viewer with PUBLIC_URL=/ohif/ APP_CONFIG=config/myConfig.js yarn build (note the two / - it is not /ohif).

:::tip
Check to make sure the app-config.js in the build is reflecting the correct routerBasename.
:::

:::tip
The PUBLIC_URL tells the application where to find the static assets and the routerBasename will tell the application how to handle the rouets
:::

Try it locally

Download the index.html and the build (against the /ohif/ path) from here

Then run the

bash
npx http-server unzipped-folder

# you can use npx serve ./dist -c ../public/serve.json as an alternative to http-server

You should be able to see


Platform Docs Docs Deployment Nginx Image Archive (`platform/docs/docs/deployment/nginx--image-archive.md`)


Nginx + Image Archive

At a certain point, you may want others to have access to your instance of the
OHIF Viewer and its medical imaging data. This post covers one of many potential
setups that accomplish that. Please note, noticeably absent is user account
control.

Do not use this recipe to host sensitive medical data on the open web. Depending
on your company's policies, this may be an appropriate setup on an internal
network when protected with a server's basic authentication.

Handling Web Requests

We mitigate our first issue by allowing [Nginx][nginx] to handle incoming web
requests. Nginx is open source software for web serving, reverse proxying,
caching, and more. It's designed for maximum performance and stability --
allowing us to more reliably serve content.

More specifically, we accomplish this by using a
reverse proxy to retrieve
resources from our image archive (Orthanc), and when accessing its web admin.

A reverse proxy is a type of proxy server that retrieves resources on behalf
of a client from one or more servers. These resources are then returned to the
client, appearing as if they originated from the proxy server itself.

This setup allows us to create a setup similar to the one pictured below:

  • All web requests are routed through nginx image
  • /pacs/dicom-web is a reverse proxy for orthanc's DICOM Web endpoints, which handles DICOM requests
  • /pacs is a reverse proxy for orthanc's Web Admin, which is the UI for managing studies
  • All static resources for OHIF Viewer are served up by nginx when a matching
    route for that resource is requested

Getting Started

Requirements

Not sure if you have docker installed already? Try running docker --version
in command prompt or terminal

Setup

  • cd platform/app/.recipes/Nginx-Orthanc
  • run: docker-compose up --build
  • Navigate to 127.0.0.1 for the viewer (at first there is no study)
  • Navigate to 127.0.0.1/pacs for uploading studies via the UI, or send studies via DIMSE C-STORE to [email protected]:4242 (hint: you can use utilizes like dcm4che's storescu to send studies in bulk via the command line)

:::note
For subsequent runs, use docker-compose up -d to start the services without rebuilding the images. However, ensure you rebuild the images if you make changes to the Dockerfile. If you modify the configurations in the nginx.conf or orthanc.json files, you can restart the services by running docker-compose up, as these files are mounted as volumes.

text
Inside docker compose file you see the following volumes mounted:

volumes:
  # Nginx config
  - ./config/nginx.conf:/etc/nginx/nginx.conf
  # Logs
  - ./logs/nginx:/var/logs/nginx

:::

You can see the overview of the mentioned steps:

:::info
The following video demonstrates an outdated capture using the deprecated OpenResty-Orthanc recipe. However, it still provides insight into the steps for running the viewer with Orthanc. Use the new Nginx-Orthanc recipe for the most up-to-date instructions.
:::

Troubleshooting

Exit code 137

This means Docker ran out of memory. Open Docker Desktop, go to the advanced
tab, and increase the amount of Memory available.

Cannot create container for service X

Use this one with caution: docker system prune

X is already running

Stop running all containers:

  • Win: docker ps -a -q | ForEach { docker stop $_ }
  • Linux: docker stop $(docker ps -a -q)

Traceback (most recent call last):
File "urllib3/connectionpool.py", line 670, in urlopen
....

Are you sure your docker is running? see explanation here

Configuration

After verifying that everything runs with default configuration values, you will
likely want to update:

  • The domain: http://127.0.0.1

OHIF Viewer

The OHIF Viewer's configuration is imported from a static .js file. The
configuration we use is set to a specific file when we build the viewer, and
determined by the env variable: APP_CONFIG. You can see where we set its value
in the dockerfile for this solution:

ENV APP_CONFIG=config/docker-nginx-orthanc.js

You can find the configuration we're using here:
/public/config/docker-nginx-orthanc.js

To rebuild the webapp image created by our dockerfile after updating the
Viewer's configuration, you can run:

  • docker-compose build OR
  • docker-compose up --build

Other

All other files are found in: /docker/Nginx-Orthanc/

Service Configuration Docs
OHIF Viewer [dockerfile][dockerfile] You're reading them now!
Nginx [/nginx.conf][config-nginx]
Orthanc [/orthanc.json][config-orthanc] [Here][orthanc-docs]

Next Steps

OHIF + Dcm4chee

You can follow the similar steps above to run OHIF Viewer with Dcm4chee PACS.

The recipe for this setup can be found at `platform/app/.recipes/Nginx-Dcm4chee