{"id":15209,"library":"react-photoswipe-gallery","title":"React PhotoSwipe Gallery Component","description":"react-photoswipe-gallery is a React component wrapper that integrates the PhotoSwipe JavaScript image gallery library into React applications. It simplifies the process of creating responsive image galleries by abstracting PhotoSwipe's imperative API into declarative React components like `Gallery` and `Item`. The current stable version is 4.0.0, which includes breaking changes focused on security and refactoring. The project maintains a moderate release cadence, with patch and minor updates appearing every few months, and major versions released less frequently. Its key differentiator lies in providing a native React experience for PhotoSwipe, managing the gallery's lifecycle and element references within the React component model, reducing boilerplate code, and ensuring compatibility with modern React features.","status":"active","version":"4.0.0","language":"javascript","source_language":"en","source_url":"https://github.com/dromru/react-photoswipe-gallery","tags":["javascript","photoswipe","react","gallery","typescript"],"install":[{"cmd":"npm install react-photoswipe-gallery","lang":"bash","label":"npm"},{"cmd":"yarn add react-photoswipe-gallery","lang":"bash","label":"yarn"},{"cmd":"pnpm add react-photoswipe-gallery","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core image gallery library, required for functionality.","package":"photoswipe","optional":false},{"reason":"React prop type validation, primarily for JavaScript projects.","package":"prop-types","optional":true},{"reason":"React framework, essential for component rendering.","package":"react","optional":false}],"imports":[{"note":"This library primarily uses ES Module imports. CommonJS `require` syntax may not work as expected or is not recommended.","wrong":"const { Gallery } = require('react-photoswipe-gallery')","symbol":"Gallery","correct":"import { Gallery } from 'react-photoswipe-gallery'"},{"note":"`Item` is a named export and must be destructured from the package. It represents an individual image within the gallery.","wrong":"import Item from 'react-photoswipe-gallery'","symbol":"Item","correct":"import { Item } from 'react-photoswipe-gallery'"},{"note":"A React Hook for programmatic control over the gallery, such as opening/closing. It's a named export, ensure correct camelCase spelling.","wrong":"import { UseGallery } from 'react-photoswipe-gallery'","symbol":"useGallery","correct":"import { useGallery } from 'react-photoswipe-gallery'"}],"quickstart":{"code":"import React, { useRef } from 'react';\nimport { Gallery, Item } from 'react-photoswipe-gallery';\nimport 'photoswipe/dist/photoswipe.css'; // Essential PhotoSwipe base styles\n\nconst MyPhotoGallery: React.FC = () => {\n  return (\n    <Gallery\n      options={{\n        bgOpacity: 0.8,\n        zoomAnimationDuration: 300\n      }}\n    >\n      <Item\n        original=\"https://picsum.photos/id/1018/1000/600/\"\n        thumbnail=\"https://picsum.photos/id/1018/100/60/\"\n        width=\"1000\"\n        height=\"600\"\n        caption=\"A serene landscape from Unsplash\"\n        cropped\n      >\n        {({ ref, open }) => (\n          <img\n            ref={ref as React.MutableRefObject<HTMLImageElement>}\n            onClick={open}\n            src=\"https://picsum.photos/id/1018/100/60/\"\n            alt=\"Landscape thumbnail\"\n            style={{ cursor: 'pointer', margin: '5px', borderRadius: '4px' }}\n          />\n        )}\n      </Item>\n      <Item\n        original=\"https://picsum.photos/id/1015/1000/600/\"\n        thumbnail=\"https://picsum.photos/id/1015/100/60/\"\n        width=\"1000\"\n        height=\"600\"\n        caption=\"Abstract patterns and colors\"\n        cropped\n      >\n        {({ ref, open }) => (\n          <img\n            ref={ref as React.MutableRefObject<HTMLImageElement>}\n            onClick={open}\n            src=\"https://picsum.photos/id/1015/100/60/\"\n            alt=\"Abstract thumbnail\"\n            style={{ cursor: 'pointer', margin: '5px', borderRadius: '4px' }}\n          />\n        )}\n      </Item>\n    </Gallery>\n  );\n};\n\nexport default MyPhotoGallery;\n","lang":"typescript","description":"This example demonstrates how to set up a basic image gallery using the `Gallery` and `Item` components. It includes the necessary PhotoSwipe CSS, custom options for the gallery, and correctly handles image references and click events to open the lightbox, showcasing two sample images."},"warnings":[{"fix":"Refactor captions to use plain text only. If rich text is essential, consider rendering it externally or sanitizing any HTML content rigorously before passing it, although direct HTML is no longer officially supported for security reasons.","message":"As of v4.0.0, the `caption` prop for the `Item` component no longer supports raw HTML content. This change was implemented to mitigate potential Cross-Site Scripting (XSS) vulnerabilities.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Update `Item` components to use the ref callback pattern correctly. Ensure the `ref` provided by the render prop is always assigned to the target HTML element, e.g., `ref={ref as React.MutableRefObject<HTMLElement>}` in TypeScript, and remove any explicit `ref` casting if previously used.","message":"Version 3.0.0 introduced significant changes to how `ref` props are handled for `Item` components. The `ref` type transitioned from a ref object to a ref callback, and passing `ref` to the underlying DOM node became mandatory even for single items. Manual casting of `ref` is also no longer required.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Ensure that your installed `photoswipe` package version adheres to the peer dependency requirements specified by `react-photoswipe-gallery`. Upgrade or downgrade `photoswipe` as necessary to match the expected range.","message":"This library has a strict peer dependency on `photoswipe`. Incompatible versions between `react-photoswipe-gallery` and `photoswipe` can lead to runtime errors, unexpected behavior, or a completely non-functional gallery. Consult `react-photoswipe-gallery`'s `package.json` for the exact compatible `photoswipe` version range.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"It is strongly recommended to upgrade to `react-photoswipe-gallery` v4.0.0 or later to benefit from the built-in XSS protection. If upgrading is not immediately possible, meticulously sanitize all content provided to the `caption` prop to prevent arbitrary script execution.","message":"Prior to v4.0.0, the `caption` prop in the `Item` component was vulnerable to Cross-Site Scripting (XSS) attacks if unsanitized user-generated HTML was passed directly. This was addressed by removing HTML support in v4.0.0.","severity":"gotcha","affected_versions":"<4.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Ensure the `ref` prop passed down from the `Item` component's render function is correctly assigned to your `<img>` or `<a>` element, like `ref={ref as React.MutableRefObject<HTMLImageElement>}` (for TypeScript) or `ref={(el) => { if (ref) ref.current = el; }}` for a callback pattern.","cause":"Incorrectly assigning or failing to assign the `ref` object provided by the `Item` component's render prop to the actual DOM element, especially after the v3.0.0 `ref` handling changes.","error":"TypeError: Cannot read properties of undefined (reading 'current') OR TypeError: ref is not a function"},{"fix":"Verify that `Item` components are always direct children of a `Gallery` component. Ensure `Item` is imported as a named export: `import { Item } from 'react-photoswipe-gallery'`.","cause":"Attempting to render `Item` outside of `Gallery` or using an incorrect import statement (e.g., a default import instead of a named import for `Item`).","error":"Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports."},{"fix":"First, install `photoswipe` (`npm install photoswipe`) and ensure its version is compatible. Then, add `import 'photoswipe/dist/photoswipe.css';` to your application's entry point or relevant component file to include the necessary styles.","cause":"Missing the required PhotoSwipe CSS import, or `photoswipe` itself is not correctly installed or compatible with the `react-photoswipe-gallery` version.","error":"PhotoSwipe: Core has not been initialized. OR PhotoSwipe is not defined."}],"ecosystem":"npm"}