You want to add a PhotoSwipe lightbox to your Astro project and still be able to use Astro's automatic image optimization?
It's simple.
Example page
Example code
Example code with ViewTransitions
1) Install photoswipe from npm
npm i photoswipe --save
2) Add this code to your .astro file
---
import { Image, getImage } from "astro:assets";
import image from "/src/assets/image.jpg";
const optimizedImage = await getImage({ src: image, width: 1920 });
---
<div id="gallery">
<a
href={optimizedImage.src}
data-pswp-width={optimizedImage.attributes.width}
data-pswp-height={optimizedImage.attributes.height}
target="_blank"
>
<Image src={image} alt={"alt"} height={350} />
</a>
...
</div>
<script>
import PhotoSwipeLightbox from "photoswipe/lightbox";
import "photoswipe/style.css";
const lightbox = new PhotoSwipeLightbox({
gallery: "#gallery",
children: "a",
pswpModule: () => import("photoswipe"),
});
lightbox.init();
</script>
You can use the same optimizedImage for the Image tag, but I prefer generating a much lower resolution version for the thumbnail and a higher resolution version for PhotoSwipe to optimize performance.
If you are using ViewTransitions, you need to modify your script tag slightly.
<script>
import PhotoSwipeLightbox from "photoswipe/lightbox";
import "photoswipe/style.css";
let lightbox: PhotoSwipeLightbox;
document.addEventListener("astro:page-load", () => {
lightbox = new PhotoSwipeLightbox({
gallery: "#gallery",
children: "a",
pswpModule: () => import("photoswipe"),
});
lightbox.init();
});
document.addEventListener("astro:before-swap", () => {
lightbox.destroy();
});
</script>
You can find a ready-to-use PhotoSwipe component in my repo, which loads all images from a given folder automatically.
Adding an image gallery doesn't mean you cannot have perfect Lighthouse scores 😁
Top comments (4)
Thank you! It doesn't work in my vercel deployment tho, only locally...
Are you using Vercel's image optimization service?
No, I don't think so, only if that is the default. I fixed it tho. The problem was, that the styles, where not present in the deployment. The import:
import "photoswipe/style.css";
, was located in the script tag. I moved it --- here ---, in the astro meta section. Now everything works fine. Thank you again for the tutorial! This is the first time I am using astro and the tutorial was exactly what I was looking for!Thank you so much, probably saved a couple of hours for me <3