React Photo Album
React Photo Album is a responsive React component designed for building dynamic photo galleries, currently at version 3.6.0. It offers three distinct layout options: rows, columns, and masonry, each powered by sophisticated dynamic programming algorithms to ensure optimal arrangement and visual balance. Its rows layout, inspired by the Knuth and Plass algorithm, minimizes deviations from a target row height, preventing stretched images or awkward last rows. The columns layout dynamically balances content, while masonry places photos into the shortest column. The library is actively maintained with regular updates and emphasizes performance, SSR compatibility, built-in TypeScript definitions, and automatic responsive image handling. It serves as a re-engineered alternative to `react-photo-gallery`, supporting React 18+ and Node 18+ and requiring modern ESM-compatible bundlers.
Common errors
-
ReferenceError: require is not defined (for 'react-photo-album')
cause Attempting to use CommonJS `require()` syntax in an ESM-only environment.fixChange `const PhotoAlbum = require('react-photo-album');` to `import PhotoAlbum from 'react-photo-album';` (or specific named imports if applicable). -
Layout appears unstyled, photos stacked, or missing visual formatting.
cause The required CSS stylesheet for the chosen layout has not been imported.fixAdd the appropriate CSS import: `import 'react-photo-album/styles.css';` for the aggregate `PhotoAlbum` component, or `import 'react-photo-album/rows.css';` (or `columns.css`/`masonry.css`) for layout-specific components. -
Warning: Each child in a list should have a unique 'key' prop.
cause Multiple `Photo` objects in the `photos` array have identical `id` properties, leading to React key collision.fixEnsure that each object in the `photos` array has a unique `id` property, or explicitly provide a unique `key` prop for each photo object. This issue was specifically addressed for duplicate photos in v3.5.1. -
Layout looks corrupted, some photos are missing, or calculation errors occur.
cause One or more `Photo` objects provided to the component have `width` or `height` properties set to zero or an invalid value.fixVerify that all `Photo` objects in your `photos` array have valid `width` and `height` numerical values greater than zero.
Warnings
- breaking Node.js and React Version Upgrade: `react-photo-album` v3.0.0 and later require Node.js 18+ and React 18+. Projects on older Node.js or React versions must upgrade their environment.
- breaking ESM-only and Modern Bundler Requirement: Since v3.0.0, the library is distributed as ESM-only. It requires a modern, ESM-compatible bundler (e.g., Vite, Webpack 5 with appropriate configuration). CommonJS environments or older bundlers will encounter import errors.
- breaking CSS Stylesheet is Required: Starting with v3.0.0, CSS-in-JS styling was replaced with external CSS stylesheets. Developers must explicitly import the relevant CSS file for the chosen layout. Omitting this will result in an unstyled or broken layout.
- breaking Changed Render Prop API: In v3.0.0, several `render` props (e.g., `renderContainer`, `renderPhoto`) and `componentsProps` were replaced with more granular and modern APIs like `render.container`, `render.image`, `componentsProps.container`, etc.
- gotcha Photos Must Have Valid Dimensions: All `Photo` objects provided to the component must include `width` and `height` properties, and these values must be greater than zero. Supplying zero-dimension photos can lead to corrupted or empty layouts.
- gotcha Unique Keys for Photos: Providing an array of photos with identical `id` or `key` properties can lead to React key collision warnings and potential rendering issues, especially when adding or removing photos.
Install
-
npm install react-photo-album -
yarn add react-photo-album -
pnpm add react-photo-album
Imports
- PhotoAlbum
import { PhotoAlbum } from 'react-photo-album'; const PhotoAlbum = require('react-photo-album');import PhotoAlbum from 'react-photo-album';
- RowsPhotoAlbum
import RowsPhotoAlbum from 'react-photo-album';
import { RowsPhotoAlbum } from 'react-photo-album'; - Photo
import { Photo } from 'react-photo-album';import type { Photo } from 'react-photo-album'; - CSS Styles
/* No explicit CSS import */
import 'react-photo-album/styles.css'; // For PhotoAlbum (3-in-1 component) import 'react-photo-album/rows.css'; // For RowsPhotoAlbum
Quickstart
import { RowsPhotoAlbum } from 'react-photo-album';
import 'react-photo-album/rows.css';
const photos = [
{ src: 'https://images.unsplash.com/photo-1594904005118-a6825c9b2e2d', width: 800, height: 600, alt: 'A scenic landscape' },
{ src: 'https://images.unsplash.com/photo-1506157788612-fc905187e5cf', width: 1600, height: 900, alt: 'City skyline at night' },
{ src: 'https://images.unsplash.com/photo-1549721727-b089b2f6c0f0', width: 1200, height: 800, alt: 'Close-up of a flower' },
{ src: 'https://images.unsplash.com/photo-1510798083980-0a14d5f479d2', width: 900, height: 1200, alt: 'Person hiking on a mountain' },
{ src: 'https://images.unsplash.com/photo-1509343206535-c3f2b6a2f8d0', width: 1000, height: 750, alt: 'Abstract art piece' }
];
export default function Gallery() {
return (
<RowsPhotoAlbum
photos={photos}
targetRowHeight={250}
spacing={8}
onClick={({ index }) => console.log(`Clicked photo at index: ${index}`)}
/>
);
}