Aller au contenu

Importer dynamiquement des images

Les images locales doivent être importées dans les fichiers .astro afin de les afficher. Il y aura des moments où vous voudrez ou devrez importer dynamiquement les chemins de vos images au lieu d’importer explicitement chaque image individuelle.

Dans cette recette, vous apprendrez à importer dynamiquement vos images en utilisant la fonction import.meta.glob de Vite. Vous allez construire un composant de carte qui affiche le nom, l’âge et la photo d’une personne.

  1. Créez un nouveau dossier assets sous le répertoire src et ajoutez vos images dans ce nouveau dossier.

    • Répertoiresrc/
      • Répertoireassets/
        • avatar-1.jpg
        • avatar-2.png
        • avatar-3.jpeg
  2. Créez un nouveau composant Astro pour votre carte et importez le composant <Image />.

    src/components/MyCustomCardComponent.astro
    ---
    import { Image } from 'astro:assets';
    ---
  3. Spécifiez les props que votre composant recevra afin d’afficher les informations nécessaires sur chaque carte. Vous pouvez optionnellement définir leurs types, si vous utilisez TypeScript dans votre projet.

    src/components/MyCustomCardComponent.astro
    ---
    import { Image } from 'astro:assets';
    interface Props {
    imagePath: string;
    altText: string;
    name: string;
    age: number;
    }
    const { imagePath, altText, name, age } = Astro.props;
    ---
  4. Créez une nouvelle variable images et utilisez la fonction import.meta.glob qui retourne un objet contenant tous les chemins d’accès aux images dans le dossier assets. Vous devrez également importer le type ImageMetadata pour vous aider à définir le type de la variable images.

    src/components/MyCustomCardComponent.astro
    ---
    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}')
    ---
  5. Utilisez les props pour créer le balisage de votre composant de carte.

    src/components/MyCustomCardComponent.astro
    ---
    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}');
    ---
    <div class="card">
    <h2>{name}</h2>
    <p>Age: {age}</p>
    <Image src={} alt={altText} />
    </div>
  6. Dans l’attribut src, passez l’objet images et utilisez la notation entre crochets pour le chemin de l’image. Assurez-vous ensuite d’invoquer la fonction glob.

    Puisque vous accédez à l’objet images qui a un type inconnu, vous devriez aussi throw une erreur dans le cas où un chemin de fichier invalide est passé en tant que prop.

    src/components/MyCustomCardComponent.astro
    ---
    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>
  7. Importer et utiliser le composant carte dans une page Astro, en passant les valeurs pour les props.

    src/pages/index.astro
    ---
    import MyCustomCardComponent from '../components/MyCustomCardComponent.astro';
    ---
    <MyCustomCardComponent
    imagePath="/src/assets/avatar-1.jpg"
    altText="Une photo de Priya sur fond de mur de briques."
    name="Priya"
    age={25}
    />