#import glob images

29 messages · Page 1 of 1 (latest)

velvet shuttle
#

I'm trying to import a folder of images at once for them to be rendered into a single component. The following works in dev

const badges = await Astro.glob("/src/components/badges/*").then((files) => {
  return files.map((file) => file.default)
});

And then in the component, a badges.map((badge) => <Image src={badge} />)

However, once the site is built, the images are not there. Am I missing a configuration? This is Astro 4.4.12

ancient cragBOT
#

Hi @velvet shuttle. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

In Astro, local images must be imported into the file in order to be used. If you want to dynamically import the image paths of your images instead of explicitly importing each individual image, you can use Vite’s import.meta.glob function.

Here's an example of how to use import.meta.glob to import images dynamically:

---import type { ImageMetadata } from 'astro';import { Image } from 'astro:assets';
interface Props { imagePath: string; altText: string; name: string; age: number;}
const { imagePath, altText, name, age } = Astro.props;const images = import.meta.glob<{ default: ImageMetadata }>('/src/assets/*.{jpeg,jpg,png,gif}');if (!images**imagePath]) throw new Error(`"${imagePath}" does not exist in glob: "src/assets/*.{jpeg,jpg,png,gif}"`);---<div class="card"> <h2>{name}</h2> <p>Age: {age}</p> <Image src={images[imagePath** ()} alt={altText} /></div>

In this example, images is an object that contains all of the image paths inside the assets folder. The imagePath prop is a string that contains the path to the image that you want to display. The import.meta.glob() is doing the work of finding the image path that matches the imagePath prop and handling the import for you.

If you're still having issues, it might be a bug related to Astro's build process. There have been reported issues on GitHub where image imports work in development but not in production. You might want to check if your issue is similar to these and if the proposed solutions work for you.

#

@velvet shuttle kapa.ai is still learning and improving, please let us know how it did by reacting below

velvet shuttle
#

Ah that first recipe looks perfect, I'll try that.

#

@ancient crag is there a difference between Astro.glob and import.meta.glob?

ancient cragBOT
#

Let me check the knowledge base for you. One moment! :books:

#

Yes, there are differences between Astro.glob and import.meta.glob.

Astro.glob is a function provided by Astro that allows you to load many local files into your static site setup. It only takes one parameter: a relative URL glob of which local files you’d like to import. It’s asynchronous, and returns an array of the exports from matching files. However, Astro.glob can only be used in .astro files.

On the other hand, import.meta.glob is a feature provided by Vite (the build tool that Astro uses under the hood). It can be used anywhere in the project, not just in .astro files. import.meta.glob can return functions that import the file content, rather than returning the content itself. This import includes all styles and scripts for any imported files. These will be bundled and added to the page whether or not a file is actually used, as this is decided by static analysis, not at runtime. import.meta.glob returns a map of a file’s path to its content, while Astro.glob returns a list of content. import.meta.glob can optionally take an array of glob strings, rather than a single string.

Here are some scenarios where you might want to use import.meta.glob instead of Astro.glob:

  • You need this feature in a file that isn’t .astro, like an API route.
  • You don’t want to load each file immediately.
  • You want access to each file’s path.
  • You want to pass multiple patterns; for example, you want to add a “negative pattern” that filters out certain files.
#

@velvet shuttle kapa.ai is still learning and improving, please let us know how it did by reacting below

velvet shuttle
#

I found one of my issues. I was pointing to /src in the glob, when I should have pointed to @components/ to resolve more magically.

#

Well, that didn't work as expected either. It still returns the filepaths as /src when that doesn't exist. I tried moving to the /public folder but it has the same problem

#

@ancient crag When I view source of the image, it points to the /src directory. But that doesn't exist when the site is built. Where should that be pointing?

ancient cragBOT
#

Let me check the knowledge base for you. One moment! :books:

#

When you build your Astro project, the source files in the /src directory are compiled into a production-ready version and output to the /dist directory. This means that the /src directory does not exist in the built site, and any paths pointing to the /src directory will not work.

For local images stored in the src/ directory, you should import the image into your .astro file and then use the import name as the src value. Here's an example:

---import { Image } from 'astro:assets';
import myImportedImage from '../assets/my-local-image.png'---
<Image src={myImportedImage} alt="descriptive text" />

For images in the public/ directory, use the image’s file path relative to the public folder:

---import { Image } from 'astro:assets';---
<Image src="/images/my-public-image.png" alt="descriptive text" width="200" height="150"/>

For remote images, use the image’s full URL as the src value:

---import { Image } from 'astro:assets';---
<Image src="<https://example.com/remote-image.jpg"> alt="descriptive text" width="200" height="150" />

In the built site, the paths to the images will be relative to the root of the site, not the /src directory.

Sources:


Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@velvet shuttle kapa.ai is still learning and improving, please let us know how it did by reacting below

velvet shuttle
#

@ancient crag maybe I don't understand the file structure in order to get this setup. Right now I have a /badges directory in /src. I'm using const badges = import.meta.glob('../badges/*.png'); to get all of the images. This returns files in the .astro component, but the images are broken in the site. How do I create the proper structure for this to work?

ancient cragBOT
#

Let me check the knowledge base for you. One moment! :books:

#

The issue you're experiencing might be due to the relative path you're using in import.meta.glob. The path should be relative to the project root, not the current file.

Here's how you can adjust your code:

const badges = import.meta.glob('/src/badges/*.png');

This will return an object where the keys are the paths to the images and the values are functions that when called, will return a promise that resolves to the module.

To use these images in your component, you can map over the badges object and call each function to import the image. Here's an example:

---
import { Image } from 'astro:assets';
const badges = import.meta.glob('/src/badges/*.png');
const badgeModules = Object.values(badges).map((importFn) => importFn());
---

{badgeModules.map((badge) => (
  <Image src={badge.default} />
))}

In this example, badge.default is the URL of the imported image.

Remember, the src directory does not exist in the built site. When you build your site, Astro will copy your images from the src directory to the appropriate location in the dist directory, and update the URLs in your code to point to the new location of the images.

Sources:


Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@velvet shuttle kapa.ai is still learning and improving, please let us know how it did by reacting below

velvet shuttle
#

Ok I've seen this before when using Astro.glob, the /src now has @fs/ at the beginning of the path. I'm going to publish and see what that resolves to.

#

Ok that rendered absolutely nothing...

#

Let me try exactly what is in the example

#

Ok the example doesn't render when using it exactly. Updating it from badge.default to badge works in dev. And the src in the view-source is different from anything I've seen before, it now has _image?href= as the beginning. This looks promising, going to publish.

#

Looks like the build failed because I was missing sharp, did a npm i sharp to include. Build completes locally now

#

Ok that works in the most simple form. Now need to add some logic, but at least I see images in prod.

velvet shuttle
#

Alright, this won't work the way I want it to. While the images will come in with the most basic example, if I try to conditionally import them I get nothing. Maybe I'm just stretching the possibilities of Astro too thin

#

I guess I'll just need to import them individually and hope that it works