DEV Community

Petrovicz
Petrovicz

Posted on • Updated on

Astro + PhotoSwipe

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
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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 😁
Lighthouse scores

Top comments (0)