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 (3)

Collapse
 
jonasfroeller profile image
Jonas • Edited

Thank you! It doesn't work in my vercel deployment tho, only locally...

Collapse
 
petrovicz profile image
Petrovicz

Are you using Vercel's image optimization service?

Collapse
 
jonasfroeller profile image
Jonas

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!