React Medium-style Image Zoom
React Medium-style Image Zoom is a JavaScript library providing an accessible, high-fidelity image zooming experience inspired by Medium.com, specifically designed for React applications. Currently stable at version `5.4.3`, the project maintains an active release cadence with frequent patch and minor updates addressing bug fixes and introducing new features. A key differentiator is its comprehensive support for various image and content types, including standard `<img>` tags (with `object-fit`, `object-position`, `loading="lazy"`), `<div>` and `<span>` elements with `background-image` properties, `<picture>`, `<figure>`, and even `<svg>`. The library prioritizes accessibility, offering robust screen reader support across major platforms (JAWS, NVDA, VoiceOver, TalkBack). It integrates seamlessly with modern React frameworks like Next.js and Gatsby, requiring React `^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0` and React DOM as peer dependencies. Notably, it boasts zero *direct* runtime dependencies, relying on native browser features like the `<dialog>` element and `ResizeObserver` for its core functionality. It expects an `ES2021` build target, potentially requiring transpilation for older environments.
Common errors
-
An empty string was passed to the src attribute
cause Occurs when the `<img>` element passed as a child to the `Zoom` component is rendered with an empty or undefined `src` prop.fixEnsure that the `src` prop of the `<img>` element always contains a valid image URL when the `Zoom` component is rendered. If the `src` is dynamic, render `Zoom` only after the `src` is available, or use a placeholder. -
TypeError: Cannot read properties of undefined (reading 'appendChild') or other hydration errors during SSR.
cause Issues during server-side rendering or subsequent client-side hydration, often related to the client-only nature of certain components or browser API dependencies.fixUpgrade to `react-medium-image-zoom` v5.4.3 or newer for improved SSR compatibility. Ensure your build toolchain correctly processes the 'use client' directive if you're using React Server Components. -
Image does not zoom or zooms incorrectly when placed inside another modal or dialog component.
cause Interference from parent dialog's CSS stacking context, event handlers (e.g., click-outside-to-close), or focus management.fixRefer to the library's documentation for specific patterns to handle nested dialogs. Recent versions (>=5.2.11) include fixes for zooming inside dialogs; upgrading may resolve the issue. You might also need to adjust `z-index` properties or `overflow` styles of the parent container.
Warnings
- gotcha The package is built for ES2021 environments. Older browsers may require additional transpilation or polyfills for the library to function correctly, particularly for features like Promise, async/await, and modern array methods.
- gotcha This library relies on native browser features such as the `<dialog>` HTML element and `ResizeObserver` API. Ensure your target browsers support these APIs or provide appropriate polyfills for wider compatibility.
- gotcha For compatibility with React Server Components (RSC) in frameworks like Next.js, versions >=5.2.10 include a 'use client' directive in its ESM output. This means components utilizing `react-medium-image-zoom` will be rendered on the client side.
- gotcha Prior to v5.4.3, users might encounter issues with React Server-Side Rendering (SSR), leading to hydration mismatches or errors during server compilation.
Install
-
npm install react-medium-image-zoom -
yarn add react-medium-image-zoom -
pnpm add react-medium-image-zoom
Imports
- Zoom
import { Zoom } from 'react-medium-image-zoom'import Zoom from 'react-medium-image-zoom'
- styles.css
import 'react-medium-image-zoom/dist/styles.css'
- UncontrolledProps
import { UncontrolledProps } from 'react-medium-image-zoom'import type { UncontrolledProps } from 'react-medium-image-zoom'
Quickstart
import React from 'react'
import Zoom from 'react-medium-image-zoom'
import 'react-medium-image-zoom/dist/styles.css'
export const MyZoomableImage = () => (
<Zoom>
<img
alt="That Wanaka Tree, New Zealand by Laura Smetsers"
src="https://rpearce.github.io/react-medium-image-zoom/static/media/thatwanakatree.ed672a9e.jpg"
width="500"
loading="lazy"
/>
</Zoom>
)
// Example of using custom content (more advanced)
import { ICompress, IEnlarge } from 'react-medium-image-zoom/dist/ui'
export const MyCustomZoomContent = () => (
<Zoom
overlayBg='rgba(0, 0, 0, 0.9)'
classDialog='custom-zoom-dialog'
IconUnzoom={ICompress}
IconZoom={IEnlarge}
>
<img
alt="Another image with custom zoom"
src="https://rpearce.github.io/react-medium-image-zoom/static/media/another-image.jpeg"
width="400"
/>
</Zoom>
)