Astrowind - Image Component
08/10/2024, SatSearching for Images
Astro comes with a default image component that you can use to load your images from the /src/assets folder.
From the actual documentation page,
---
// import the Image component and the image
import { Image } from 'astro:assets';
import myImage from "../assets/my_image.png"; // Image is 1600x900
---
<!-- `alt` is mandatory on the Image component -->
<Image src={myImage} alt="A description of my image." />
Using Astro's Image
component is useful in that it helps you perform optimizations to your images on the final build. It is able to output to webp format as well as set the width and height for them to improve site layout performance.
However, one of the downside of using the default component is that you have to load the images one by one. Astro also has a suggestion for dynamic images using import.meta.glob
, but it still is not as dynamic as compared to that of Astro's glob
method.
Supposedly, that you have images in folders located in the ''/src/assets/images/'. There is the expectation that '/src/assets/images/**' pattern will return all your images within those folders when using the that pattern with import.meta.glob
const images = import.meta.glob<{ default: ImageMetadata }>('/src/assets/images/**'.{jpeg,jpg,png,gif}');
But it does not yield any results in the images results.
While if you to use Astro.glob
with that search pattern,
const images = await Astro.glob('/src/assets/images/**');
the images will provide the results.
To retain flexibility in searching for images and as well as customization for the , it is helpful go midway between using Astro's default Image
component and the plain <img>
tag by using Astrowind's Image
component.
To search for images dynamically in your src/assets folder, we will define
the getImageMetas
function in the src/utils/images.ts
file.
We need this function because we wish to narrow down the results that is returned from using Astro.glob
by finding only the image names that we supply to it.
export const getImageMetas = async (searchImages, allImages) => {
const imgNameToEntry = {};
allImages.forEach((images, imagesIndex) => {
const searchedNames = images.default.src;
let searchImageName = '';
let searchImageEntry: Record<any, any> = {};
const foundImages = searchImages.filter((searchImg) => {
// Account for the differences in the image file name output
// between development and final build
// Build
// my_image.DySEU_5O.jpg
// Dev
// my_image.jpg
if (searchedNames.indexOf(`/${path.parse(searchImg).name}`) > -1) {
searchImageName = searchImg;
searchImageEntry = allImages[imagesIndex];
return true;
} else {
return false;
}
});
if (foundImages.length > 0) {
imgNameToEntry[searchImageName] = searchImageEntry;
}
});
return imgNameToEntry;
}
Within your .astro file, you will define the images that you want to search for in the searchImages
array. You will need to get all images from your image folder because Astro.glob
does not support the use of dynamic strings in which it uses to search. Finally, call the getImageMetas
by passing images to search for and all the images from your image folder.
It is rather unfortunate that Astro doesn't allow you to pass in Astro.glob
into our getImageMetas
function because the glob
function is restricted for use in Astro templates, so you will need to
repeat this line in all the other .astro templates that need to perform
dynamic image searches.
const searchImages = ['some-image.jpg', 'another-image.jpg'];
const allImages = await Astro.glob('/src/assets/images/**');
const imagesMetas = await getImageMetas(searchImages, allImages);
The output of imagesMetas
will look like the following
{
default: {
src: '/@fs/home/my-repo-paths/src/assets/images/some-image.jpg?origWidth=1024&origHeight=1024&origFormat=jpg',
width: 1024,
height: 1024,
format: 'jpg'
},
[Symbol(Symbol.toStringTag)]: 'Module'
},
{
default: {
src: '/@fs/home/my-repo-paths/src/assets/images/another-image.jpg?origWidth=1024&origHeight=1024&origFormat=jpg',
width: 1024,
height: 1024,
format: 'jpg'
},
[Symbol(Symbol.toStringTag)]: 'Module'
},
One can start using webp images from the beginning to gain the additional level of image optimization for your images if you forego using Astro's image component.