A static photography portfolio/gallery built with Astro and TypeScript.
This is the Astro rewrite of the earlier Gatsby-based version.
- 100% static output
- Album index with responsive cards and optimized image rendering
- Album detail pages with masonry layout
- Photo detail pages with:
- full-resolution zoom modal
- downloadable original image
- EXIF summary (camera/lens/settings/location fields)
- Dark/light theme toggle with persistent preference
- Astro
- TypeScript
- React islands (
@astrojs/react) - Bulma + react-bulma-components
astro:assets+ Sharp for image optimizationexifrfor EXIF extraction
Main content location:
src/assets/images/*→ each subfolder is treated as an album
Example:
src
├── images
│ └── input
│ ├── Album1 -> /mnt/real/path/to/album1
│ └── Album2 -> /mnt/real/path/to/album2
Routes:
/albums list/albums/[slug]/album page/albums/[album_slug]/[slug]/photo page/gear/gear page/map/map page
Edit src/config.tsx:
title: site/page titlegears: camera/lens data used by/gearflatten_index: navbar label/count behaviorenable_map_page,enable_gear_page: toggle navbar entriesexifr_filter: choose which EXIF keys are shown on photo detail pages
Site-level config:
- astro.config.mjs (
site,base, output mode, integrations)
- Install dependencies
pnpm install - Add your albums, Put album folders (or symlinks) under
src/assets/images/. - Start development server
pnpm dev - Build static site
pnpm build. Build output goes todist/andpnpm preview.
- Album and photo sorting are based on
DateTimeOriginalwhen available. - If EXIF parsing fails for a photo, it still gets included with fallback metadata.
Inspired by Chris Benninger's project fussel, then rewritten in TypeScript for Gatsby, and now migrated to Astro.
MIT — see LICENSE.