Direkt zum Hauptinhalt Direkt zum Menü

NONCHALANT

Using images

Astro has inbuilt image handling components and utilities. Find here the different approaches and best practice recommendation for the most common use cases.

Images can be stored in /src or /static – Images in /src are transformed by astro (resized, optimized etc.) and the files in /static are kept as they are. Thus in general, images should always go in /src because we want them to be optimized. Things like favicons can go into /static.

Static images

Static images are referenced through their absolute paths and astro has no knowledge of their content only of their location. So given the image /static/example.png you can reference /example.png and the exact same file will be rendered.

Astro assets (Astro transformed images)

The default location for assets is /src/assets and there is an import alias @assets to that location. However images can also be co-located with their importing files (or some other place within /src).

When astro loads the images they are turned into ImageMetadata which is an object containing things like mime type, size etc. With this object astro can created multiple derivative files (“transform”) such as different file types, sizes.

Loading assets

Astro can be told to load images in multiple ways:

Using assets within templates

Once loaded an image (resolved to ImageMetadata) can used in multiple ways:

An example of an astro page with an image:

---
import img1 from "@assets/img1.png";
---

<Layout>
  <div class="row">
    <div class="col-xs-7 col-md-3">
      <Image src={img1} widths={[500, 1000, 1500]} sizes="(max-width: 900px) 90vw, (max-width:1100px) 70vw, 40vw">
    </div>
  </div>
</Lyout>

Using assets in MDX content

ℹ️ For frontmatter image references, use the image schema helper and render that with the <Image /> component.

There are two possible solutions to loading optimized images from within markdown body content:

  1. ✅ Using a top-of-file import and the <Image /> component:

    ---
    title: Lorem Ipsum
    ---
    
    import { Image } from "astro:assets";
    import img1 from "@assets/img1.png";
    
    <Image src={img1} >
  2. ✅ For use cases where the client is working with the content files (which is probably the case, because why else would you use mdx and not .astro files?) – You can do the following:

    In the MDX file, load the image with standard markdown syntax:

    ![Image alt text](img.png)

    Then when it comes to rendering the markdown content, customize the component used to render the image and set the widths and sizes attributes for optimized responsive images:

    ---
    // An astro component rendering markdown content
    // such as /pages/features/[id].astro
    import { FeatureImage } from "@components/FeatureImage.astro";
    
    // ...
    
    const { entry } = Astro.props;
    const { Content } = await render(entry);
    ---
    
    <Content components={{ img: FeatureImage }} />

    And the FeatureImage.astro looks like this:

    ---
    import { Image } from 'astro:assets';
    import type { ImageMetadata } from 'astro';
    
    type Props = {
      // src can also be string when the path was an absolute
      // path, a remote URL or when the image was actually written
      // as plan html <img> not with the markdown syntax.
      src: string | ImageMetadata;
      alt: string;
    };
    
    const { src, alt } = Astro.props;
    ---
    
    {
      typeof src === 'string' ? (
        <img src={src} alt={alt} />
      ) : (
        <Image
          {src}
          {alt}
          widths={[500, 1000, 1500]}
          sizes="(max-width: 900px) 90vw, (max-width:1100px) 70vw, 40vw"
        />
      )
    }