How to create an Image Gallery with Astro Framework, in Less than an Hour?

How to create an Image Gallery with Astro Framework, in Less than an Hour?
Photo by Zalfa Imani / Unsplash

Astro is an exceptional frontend framework for effortlessly constructing high-performance websites and applications. It empowers developers to create modular components using a blend of JavaScript, HTML, and CSS, which are subsequently compiled into finely-tuned static assets.

Moreover, Astro offers robust support for server-rendering and dynamic loading, rendering it an exceedingly versatile option for constructing static, dynamic, or hybrid websites.

In this article, we will create a gallery website using Astro.

Creating a gallery website using Astro with modals for each image and dedicated pages requires combining Astro's static site generation capabilities with some front-end interactivity. Below are some code snippets and explanations for key parts of the project.

1. Setting Up Your Astro Project

First, initialize your Astro project:

npm init astro

Choose the starter template, or set up a custom configuration.

In your src/pages directory, create an index.astro file. This will be your main gallery page.

---
// Import components and any necessary data here
import ImageComponent from '../components/ImageComponent.astro';
// Assuming you have an array of images
const images = [{ src: 'path/to/image1.jpg', alt: 'Image 1' }, ...];
---
<html>
  <head>
    <title>My Astro Gallery</title>
  </head>
  <body>
    <div class="gallery">
      {images.map((image) => (
        <ImageComponent src={image.src} alt={image.alt} />
      ))}
    </div>
  </body>
</html>

3. Creating the Image Component

In your src/components directory, create an ImageComponent.astro file. This component will handle displaying each image and linking to its dedicated page.

---
// Props passed to the component
export let src = '';
export let alt = '';
---
<div class="image-container">
  <a href={`/image/${encodeURIComponent(alt)}`}>
    <img src={src} alt={alt} />
  </a>
</div>

4. Creating Individual Image Pages

Create a dynamic route for individual image pages. In src/pages/image, add a [slug].astro file.

---
// Dynamic slug
const { slug } = Astro.request.params;
const image = findImageBySlug(slug); // Implement this function to find the image data
---
<html>
  <head>
    <title>{image.title}</title>
  </head>
  <body>
    <img src={image.src} alt={image.title} />
    <p>{image.description}</p>
  </body>
</html>

5. Styling Your Components

Add CSS in a global stylesheet or inline within your components.

.gallery {
  display: flex;
  flex-wrap: wrap;
}
.image-container {
  margin: 10px;
}
.image-container img {
  width: 100%;
  height: auto;
}

6. Implementing Modals (Optional)

If you want a modal for each image on the gallery page, you would

need to add some client-side interactivity. You can use a front-end framework like Alpine.js or write vanilla JavaScript for this. Here's an example using vanilla JavaScript:

First, modify your ImageComponent.astro to include a modal structure:

---
export let src = '';
export let alt = '';
---
<div class="image-container">
  <img src={src} alt={alt} onclick="openModal('{src}', '{alt}')"/>
  <div id="myModal" class="modal">
    <span class="close" onclick="closeModal()">&times;</span>
    <img class="modal-content" id="img01">
    <div id="caption"></div>
  </div>
</div>

Then, add some JavaScript for modal functionality:

<script>
  function openModal(src, alt) {
    var modal = document.getElementById('myModal');
    var modalImg = document.getElementById('img01');
    var captionText = document.getElementById('caption');
    modal.style.display = "block";
    modalImg.src = src;
    captionText.innerHTML = alt;
  }

  function closeModal() {
    var modal = document.getElementById('myModal');
    modal.style.display = "none";
  }
</script>

And add CSS for the modal:

.modal {
  display: none;
  position: fixed;
  z-index: 1;
  padding-top: 100px;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  overflow: auto;
  background-color: rgb(0,0,0);
  background-color: rgba(0,0,0,0.9);
}

.modal-content {
  margin: auto;
  display: block;
  width: 80%;
  max-width: 700px;
}

.close {
  position: absolute;
  top: 15px;
  right: 35px;
  color: white;
  font-size: 40px;
  font-weight: bold;
  cursor: pointer;
}

7. Finalizing and Testing

  • Ensure all components are properly linked and the site is structured as you intend.
  • Test the modal functionality and navigation to individual image pages.
  • Check responsiveness and cross-browser compatibility.

This basic structure should help you get started with your Astro-based gallery website. Remember to tailor the components, styles, and functionality to your specific needs and design preferences.