LaunchFast Logo LaunchFast

Using PhotoSwipe in Astro to Build an Image Gallery

Rishi Raj Jain
Using PhotoSwipe in Astro to Build an Image Gallery

In this guide, you will learn how to use PhotoSwipe in an Astro application. You will go through the process of setting up a new Astro project, installing the PhotoSwipe module, and turning your images collection into an image gallery.

Prerequisites

You’ll need the following:

Table Of Contents

Create a new Astro application

Let’s get started by creating a new Astro project. Execute the following command:

npm create astro@latest my-app

npm create astro is the recommended way to scaffold an Astro project quickly.

When prompted, choose:

  • Empty when prompted on how to start the new project.
  • Yes when prompted if plan to write Typescript.
  • Strict when prompted how strict Typescript should be.
  • Yes when prompted to install dependencies.
  • Yes when prompted to initialize a git repository.

Once that’s done, you can move into the project directory and start the app:

cd my-app
npm run dev

The app should be running on localhost:4321.

Now, let’s move on to integrate PhotoSwipe in your Astro application.

Integrate PhotoSwipe in your Astro project

Install PhotoSwipe SDK

Execute the command below to install the necessary package for using PhotoSwipe:

npm install photoswipe

The command installs the following library:

  • photoswipe: A framework-agnostic JavaScript Image Gallery library.

Create an Image Collection

Using PhotoSwipe (with the default configuration) requires two things:

  • A parent HTML element (most commonly, a <div>) which contains all the images.
  • Each image to be enclosed in an <a> tag containing the height and width attribute of the image.

To make sure that the <a> element does not take over the styling of your <img> elements, you can use the following CSS to only render it’s children elements: display: contents;. In the example below, you are going to use the contents class by Tailwind CSS.

---
// File: src/pages/index.astro
---

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width" />
    <meta name="generator" content={Astro.generator} />
    <title>Astro</title>
  </head>
  <body>
    <div id="my-gallery" class="grid grid-cols-1 py-10 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
      <a href="https://picsum.photos/900/1600" data-pswp-width="900" data-pswp-height="1600" class="contents">
        <img
          width="900"
          height="1600"
          loading="lazy"
          decoding="async"
          src="https://picsum.photos/900/1600"
          class="absolute h-[250px] w-[300px] object-cover shadow"
        />
      </a>
      <a href="https://picsum.photos/900/1600" data-pswp-width="900" data-pswp-height="1600" class="contents">
        <img
          width="900"
          height="1600"
          loading="lazy"
          decoding="async"
          src="https://picsum.photos/900/1600"
          class="absolute h-[250px] w-[300px] object-cover shadow"
        />
      </a>
    </div>
  </body>
</html>

In minimal lines of code with PhotoSwipe, you can turn your collection of images into an interactive image gallery. You can easily do that in 3 steps:

  • Import the PhotoSwipe css.
  • Import the PhotoSwipe module.
  • Create a lightbox using PhotoSwipe.

Refer to the script below to do the above steps in this example:

---
// File: src/pages/index.astro
---

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
    <meta name="viewport" content="width=device-width" />
    <meta name="generator" content={Astro.generator} />
    <title>Astro</title>
  </head>
  <body>
    <div id="my-gallery" class="grid grid-cols-1 py-10 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
      <a href="https://picsum.photos/900/1600" data-pswp-width="900" data-pswp-height="1600" class="contents">
        <img
          width="900"
          height="1600"
          loading="lazy"
          decoding="async"
          src="https://picsum.photos/900/1600"
          class="absolute h-[250px] w-[300px] object-cover shadow"
        />
      </a>
      <a href="https://picsum.photos/900/1600" data-pswp-width="900" data-pswp-height="1600" class="contents">
        <img
          width="900"
          height="1600"
          loading="lazy"
          decoding="async"
          src="https://picsum.photos/900/1600"
          class="absolute h-[250px] w-[300px] object-cover shadow"
        />
      </a>
    </div>
    <script>
      import 'photoswipe/style.css'
      import pswpModule from 'photoswipe'
      import PhotoSwipeLightbox from 'photoswipe/lightbox'

      window.lightbox = new PhotoSwipeLightbox({
        pswpModule,
        children: 'a',
        gallery: '#my-gallery',
      })

      document.addEventListener(
        'astro:page-load',
        () => { if (lightbox) lightbox.init() },
        { once: false },
      )
    </script>
  </body>
</html>

In the code above you have done the following:

  • Imported the PhotoSwipe CSS.
  • Created a lightbox that listens to clicks on all the <a> elements, present hirerachly in the HTML element that has my-gallery as it’s id attribute.
  • Attaches an Astro page load listener and brings the lightbox in effect. This way of instantiating the lightbox is helpful as this script can be used with View Transitions enabled in your Astro application as well.

Build and Test your Astro application locally

To test the application, prepare a build and run the preview server using the command below:

npm run build && npm run preview

Conclusion

In this guide, you learned how to use PhotoSwipe in an Astro application to build an Image Gallery.

If you have any questions or comments, feel free to reach out to me on Twitter.

Learn More Using Transformers for Shiki to enrich Syntax Highlighting in Astro → Using GreenSock Animation Platform (GSAP) in Astro with View Transitions: A Step-by-Step Guide → Using GreenSock Animation Platform (GSAP) in Astro: A Step-by-Step Guide →