GitPedia

React photoswipe gallery

๐Ÿ™ React component wrapper around PhotoSwipe

From dromruยทUpdated June 27, 2026ยทView on GitHubยท

> A configurable and flexible React component wrapper around [PhotoSwipe](https://photoswipe.com/). \ > \ > โ„น๏ธ Current version of react-photoswipe-gallery is compatible with PhotoSwipe v5. \ > **If you need PhotoSwipe v4, use [react-photoswipe-gallery v1](https://github.com/dromru/react-photoswipe-gallery/tree/v1.3.11).** The project is written primarily in TypeScript, distributed under the MIT License license, first published in 2019. Key topics include: gallery, lightbox, photoswipe, react, react-photoswipe.

Latest release: v4.1.2

react-photoswipe-gallery

codecov npm

A configurable and flexible React component wrapper around PhotoSwipe.

โ„น๏ธ Current version of react-photoswipe-gallery is compatible with PhotoSwipe v5.
If you need PhotoSwipe v4, use react-photoswipe-gallery v1.

Basic Usage

javascript
import 'photoswipe/dist/photoswipe.css' import { Gallery, Item } from 'react-photoswipe-gallery' const MyGallery = () => ( <Gallery> <Item original="https://placekitten.com/1024/768?image=1" thumbnail="https://placekitten.com/80/60?image=1" width="1024" height="768" > {({ ref, open }) => ( <img ref={ref} onClick={open} src="https://placekitten.com/80/60?image=1" /> )} </Item> <Item original="https://placekitten.com/1024/768?image=2" thumbnail="https://placekitten.com/80/60?image=2" width="1024" height="768" > {({ ref, open }) => ( <img ref={ref} onClick={open} src="https://placekitten.com/80/60?image=2" /> )} </Item> </Gallery> )

Demo

Check out the Storybook to see it in action ๐Ÿš€

Stories are written as real-world examples, so you can see them at the bottom of Storybook UI in the Story tab. Or browse the source code on GitHub. It covers most of the use-cases and provides examples for configuration options.

Installation

shell
yarn add photoswipe react-photoswipe-gallery

or

shell
npm install photoswipe react-photoswipe-gallery --save

Hash Navigation

You should pass a unique id prop to <Gallery /> component, to enable hash navigation.

Optionally, you can also pass the id to <Item /> component. Otherwise, the index will be used.

javascript
const MyGallery = () => ( <Gallery id="my-gallery"> <Item id="first-pic" {/*...*/} /> <Item id="second-pic" {/*...*/} /> </Gallery> )

Example

Captions

If you want to add captions to your slides, you need to pass withCaption prop to the <Gallery />
and pass caption prop to each <Item />. If caption isn't provided - it will use alt prop.

javascript
const MyGallery = () => ( <Gallery withCaption> <Item caption="Foo" {/*...*/} /> <Item alt="Bar" {/*...*/} /> </Gallery> )

Example

Plugins

You can use native PhotoSwipe plugins with plugins prop. It accepts the function in which you should register all of your plugins, providing pswpLightbox to the plugin constructor.

Example for photoswipe-dynamic-caption-plugin:

javascript
import 'photoswipe-dynamic-caption-plugin/photoswipe-dynamic-caption-plugin.css' import PhotoSwipeDynamicCaption from 'photoswipe-dynamic-caption-plugin' const MyGallery = () => ( <Gallery plugins={(pswpLightbox) => { // register plugin const captionPlugin = new PhotoSwipeDynamicCaption(pswpLightbox, { captionContent: (slide) => slide.data.alt, }) // register another plugin // ... }} > {/*...*/} </Gallery> )

Example

Custom UI Elements

You can add custom UI elements to PhotoSwipe with uiElements prop. It accepts an array of configuration objects for custom UI elements.

javascript
const uiElements = [ // add custom UI element { name: 'custom-button', ariaLabel: 'Custom button', order: 9, isButton: true, html: { isCustomSVG: true, inner: '<path d="<ICON_PATH>" id="pswp__icn-cstm-btn"/>', outlineID: 'pswp__icn-cstm-btn', }, appendTo: 'bar', onInit: (el, pswpInstance) => { // do something on UI element's init event }, onClick: (e, el, pswpInstance) => { // do something on UI element's click event }, }, // add another custom UI element // ... ] const MyGallery = () => ( <Gallery uiElements={uiElements}> {/*...*/} </Gallery> )

Example

Custom slide content

You can add your own custom slide content with content and html props.

javascript
const MyGallery = () => ( <Gallery> <Item content={<h1>Hi!</h1>} {/*...*/} /> <Item html="<h1>Hi!</h1>" {/*...*/} /> </Gallery> )

Example

Data source

You can pass slides data to Photoswipe not only via Item component. You can also do it via dataSource prop.

javascript
const dataSource = [ { sourceId: 1, // needed to connect following data with Item component original: "https://placekitten.com/1024/768?image=1", thumbnail: "https://placekitten.com/80/60?image=1", width: "1024", height: "768", }, { sourceId: 2, ... }, { sourceId: 3, ... }, ] const MyGallery = () => ( <Gallery dataSource={dataSource}> <Item sourceId={1} // needed to connect Item component with data from dataSource > {({ ref, open }) => ( <button type="button" ref={ref} onClick={open}> Open gallery at first slide </button> )} </Item> </Gallery> )

Example

Also dataSource prop can be helpful, if you need to render only some part of images as thumbnails and show all available images in Photoswipe.

javascript
const dataSource = [ { sourceId: 1, // needed to connect following data with Item component original: "https://placekitten.com/1024/768?image=1", thumbnail: "https://placekitten.com/80/60?image=1", width: "1024", height: "768", }, { sourceId: 2, ... }, { sourceId: 3, ... }, { sourceId: 4, ... }, { sourceId: 5, ... }, ] const MyGallery = () => ( <Gallery dataSource={dataSource}> <Item sourceId={1} // needed to connect Item component with data from dataSource > {({ ref, open }) => ( <img src="https://placekitten.com/80/60?image=1" ref={ref} onClick={open} /> )} </Item> <Item sourceId={2} > {({ ref, open }) => ( <img style={imageStyles} src="https://placekitten.com/80/60?image=2" ref={ref} onClick={open} /> )} </Item> <Item sourceId={3} > {({ ref, open }) => ( <div ref={ref} onClick={open}> <p>+ 2</p> <img src="https://placekitten.com/80/60?image=3" /> </div> )} </Item> </Gallery> )

Example

Access to Photoswipe instance

If you need to get access to Photoswipe instance (for example, to subscribe on Photoswipe events or call some Photoswipe method),
you can do it via onOpen and onBeforeOpen props of Gallery component.

onBeforeOpen triggers before PhotoSwipe.init() call.

onOpen triggers after PhotoSwipe.init() call.

onBeforeOpen and onOpen will receive PhotoSwipe instance as the first argument.

javascript
const onBeforeOpen = (pswpInstance) => { pswpInstance.on('change', () => { console.log('slide was changed') }) } const onOpen = (pswpInstance) => { pswpInstance.currSlide.zoomTo( 1, { x: 0, y: 0 }, 2000, false ) } const MyGallery = () => ( <Gallery onBeforeOpen={onBeforeOpen} onOpen={onOpen}> {/*...*/} </Gallery> )

Photoswipe customization

If you need to customize Photoswipe options or Photoswipe styling
you can do it via options prop of Gallery component.

javascript
const options = { arrowPrev: false, arrowNext: false, zoom: false, close: false, counter: false, bgOpacity: 0.2, padding: { top: 20, bottom: 40, left: 100, right: 100 }, } const MyGallery = () => ( <Gallery options={options}> {/*...*/} </Gallery> )

Props

<a name="gallery-props"></a>

PropTypeRequiredDescription
idNumber or Stringโœ“ (for hash navigation)Item ID, for hash navigation
optionsObjectObject containing PhotoSwipe options and styling properties
pluginsFunctionFunction for registering PhotoSwipe plugins. You should pass photoswipeLightbox to each plugin constructor (example)
uiElementsArrayArray of configuration objects for custom UI elements. Use it for adding custom UI elements (example)
onBeforeOpenFunctionTriggers before PhotoSwipe.init() call. Use it for accessing PhotoSwipe API. It will receive PhotoSwipe instance as the first argument: (photoswipe: PhotoSwipe) => void
onOpenFunctionTriggers after PhotoSwipe.init() call. Use it for accessing PhotoSwipe API. It will receive PhotoSwipe instance as the first argument: (photoswipe: PhotoSwipe) => void
withCaptionBooleanโœ“ (for default captions)Enables built-in caption display. Use the caption prop of the Item component to control caption text (example)
withDownloadButtonBooleanโœ“ (for download button)Adds UI control for downloading the original image of the current slide (example)
dataSourceArrayArray of data for Photoswipe slides. Data source - alternative way to pass data into Photoswipe

Item

Should be children of the Gallery.

<a name="item-props"></a>

PropTypeRequiredDescription
childrenFunctionโœ“Render prop for exposing Gallery API
originalStringUrl of original image
originalSrcsetStringSrcset of original image (example)
thumbnailStringUrl of thumbnail
widthNumber or StringWidth of original image
heightNumber or StringHeight of original image
altStringAlternate text for original image
captionStringText for caption (example)
croppedBooleanThumbnail is cropped (example)
contentReactElementCustom slide content (example)
htmlStringCustom slide content (raw html) (example)
idNumber or StringItem ID, for hash navigation (example)
sourceIdNumber or Stringโœ“ (for data source)Item source ID, that will be used to identify item in dataSource array (example)

Note about Item's children render prop

Item accepts only function as children.

typescript
export interface ChildrenFnProps<NodeType extends HTMLElement> { /** * Ref callback to any html node of item. * It must be set to HTML Element in order to work. * Can be done like usual ref: ref={ref} * or callback-way if you need extra work done with node: * ref={(node) => { * ref(node) * ... * }} */ ref: (node: NodeType | null) => void /** * Function that opens the gallery at the current item */ open: (e: MouseEvent) => void /** * Function that closes the gallery */ close: () => void } <Item> {({ ref, open }) => ( <img ref={ref} onClick={open} /> )} </Item> <Item> {({ ref, open, close }) => ( <> <span ref={(node) => { ref(node) }} onClick={open} > Open gallery </span> <span ref={(node) => { ref(node) }} onClick={close} > Close gallery </span> </> )} </Item>

Hooks

useGallery

The useGallery hook returns an object with some useful methods.

PropertyTypeDescription
open(index: number) => voidThis function allows programmatically open Photoswipe UI at index
close() => voidThis function allows programmatically close Photoswipe UI

useGallery hook gets context provided by Gallery component.
So to use useGallery hook you need to store your gallery content as separate component and then wrap it into Gallery component.

javascript
const GalleryContent = () => { const { open, close } = useGallery() useEffect(() => { open(1) // you can open second slide by calling open(1) in useEffect setTimeout(() => { close() // or you can close gallery }, 5_000) }, [open, close]) return ( <div> {/* you can open second slide on button click */} <button onClick={() => open(1)}>Open second slide</button> {/* or close gallery */} <button onClick={close}>Close gallery</button> <div> <Item>...</Item> <Item>...</Item> <Item>...</Item> </div> </div> ) } const MyGallery = () => { return ( {/* Gallery component provides context for useGallery hook used in GalleryContent */} <Gallery> <GalleryContent /> </Gallery> ) }

Example 1, Example 2

Requirements

Development

shell
yarn install yarn sdks vscode

then

shell
yarn storybook

or

shell
yarn start

License

MIT

Contributors

Showing top 10 contributors by commit count.

View all contributors on GitHub โ†’

This article is auto-generated from dromru/react-photoswipe-gallery via the GitHub API.Last fetched: 6/29/2026