最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Dynamically import all images from a folder in Astro - Stack Overflow

programmeradmin3浏览0评论

I am working with Astro. The project uses quite a few images, and I want to simplify the way I currently add new images. My routes are like:

example/pictures/[collection]

( "[" and "]" stands for a dynamic route )

Allowing for example:

example/pictures/mixed-tecnique

example/pictures/graphite

example/pictures/acrylic


In the file pages/pictures/[collection].astro I want to do the following (or something similar):

---
import * as collections from "public/img/collections"

const { collection } = Astro.props
---

{collections[collection].map(imgSrc => <img src={imgSrc} />)}

So now, to have a new Collection route, I just have to create a new folder and drop the images there.

Is there any way to do something to reach the same result? Thanks in advance!!

I am working with Astro. The project uses quite a few images, and I want to simplify the way I currently add new images. My routes are like:

example./pictures/[collection]

( "[" and "]" stands for a dynamic route )

Allowing for example:

example./pictures/mixed-tecnique

example./pictures/graphite

example./pictures/acrylic


In the file pages/pictures/[collection].astro I want to do the following (or something similar):

---
import * as collections from "public/img/collections"

const { collection } = Astro.props
---

{collections[collection].map(imgSrc => <img src={imgSrc} />)}

So now, to have a new Collection route, I just have to create a new folder and drop the images there.

Is there any way to do something to reach the same result? Thanks in advance!!

Share Improve this question edited Feb 28, 2024 at 5:56 VLAZ 29.1k9 gold badges62 silver badges84 bronze badges asked Jan 15, 2023 at 15:24 Genaro BonavitaGenaro Bonavita 711 silver badge3 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 12

This is how I achieve:

---
const images = await Astro.glob("/src/assets/img/salon/*").then(files => {
  return files.map(file => file.default);
});
---

<div class="swiper">
  <!-- Additional required wrapper -->
  <div class="swiper-wrapper">
    <!-- Slides -->
    {
      images.map(image => (
        <div class="flex items-center justify-center swiper-slide">
          <img
            class="object-contain h-full rounded-lg"
            src={image}
            alt=""
            loading="lazy"
          />
        </div>
      ))
    }
  </div>
  ...
</div>

If you are using experimental assets feature:

{
  images.map(({ src /* width and height is also available */ }) => (
    <div class="flex items-center justify-center swiper-slide">
      <img
        class="object-contain h-full rounded-lg"
        src={src}
        alt=""
        loading="lazy"
      />
    </div>
  ))
}

There are a bunch of different ways to implement a feature like this but here is a simple example making use of the fast-glob library

public
  pictures
    mixed-technique
      example.png
      example.png
      example.png
    graphite
      example.png
      example.png
      example.png
    arcylic
      example.png
      example.png
      example.png
// src/pages/pictures/[collection].astro
---
import fg from 'fast-glob';

export async function getStaticPaths() {
    // get all collection folder paths: 'public/pictures/[collection]'
    const collections: string[] = fg.sync('public/pictures/*', { onlyDirectories: true })

    // Create a new route for every collection
    return collections.map(collection => {

        // Create Route
        return {
            params: {
                // Return folder name of collection as dynamic parameter [collection]
                collection: collection.split('/').pop()
            },
            props: {
                // Return array of all image srcs in collection as prop 'images'
                images: fg.sync(`${collection}/**/*.{png,jpg}`).map(img => img.replace('public/', '/'))
            }
        }
    })
}

export interface Props {
    images: string[];
}

const { collection } = Astro.params

const { images } = Astro.props
---

<html lang="en">
    <head>
        <!-- ... -->
    </head>
    <body>
        { images.map(img => <img src={img}/>) }
    </body>
</html>

Note: I used fast-glob instead of Astro.glob or import.meta.glob() because it can take a variable as an argument (makes this logic easier/more dynamic) and because it only returns an array of file/folder paths instead of also attempting to return file content

---
import { Image } from 'astro:assets';

const imageFiles = await Astro.glob('./images/*');
---

<div class="columns-1 sm:columns-2 md:columns-3 lg:columns-4 gap-3 mb-5 mx-auto w-full px-4">
  {
    imageFiles.map((img) => (
      <Image
        src={img.default}
        width="600"
        alt="Photo of a pizza"
        class="mb-3 w-full rounded"
      />
    ))
  }
</div>

发布评论

评论列表(0)

  1. 暂无评论