Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/content/docs/en/guides/images.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ i18nReady: true
import Since from '~/components/Since.astro';
import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro';
import Badge from '~/components/Badge.astro';
import RecipeLinks from "~/components/RecipeLinks.astro";


Astro provides several ways for you to use images on your site, whether they are stored locally inside your project, linked to from an external URL, or managed in a CMS or CDN!
Expand Down Expand Up @@ -609,6 +610,8 @@ import stars from "~/stars/docline.png";

The `getImage()` function is intended for generating images destined to be used somewhere else than directly in HTML, for example in an [API Route](/en/core-concepts/endpoints/#server-endpoints-api-routes). It also allows you to create your own custom `<Image />` component.

<RecipeLinks slugs={["en/recipes/build-custom-img-component" ]}/>

`getImage()` takes an options object with the [same properties as the Image component](#properties) (except `alt`).

```astro
Expand Down
126 changes: 126 additions & 0 deletions src/content/docs/en/recipes/build-custom-img-component.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
---
title: Build a custom image component
description: Learn how to build a custom image component that supports media queries using the getImage function
i18nReady: true
type: recipe
---

Astro provides two built-in components that you can use to display and optimize your images. The `<Picture>` component allows you to display responsive images and work with different formats and sizes. The `<Image>` component will optimize your images and allow you to pass in different formats and quality properties.

When you need options that the `<Picture>` and `<Image>` components do not currently support, you can use the `getImage()` function to create a custom component.

In this recipe, you will use the [`getImage()` function](/en/guides/images/#generating-images-with-getimage) to create your own custom image component that displays different source images based on media queries.

## Recipe

1. Create a new Astro component and import the `getImage()` function

```astro title="src/components/MyCustomImageComponent.astro"
---
import { getImage } from "astro:assets";
---

```

2. Create a new component for your custom image. `MyCustomComponent.astro` will receive three `props` from `Astro.props`. The `mobileImgUrl` and `desktopImgUrl` props are used for creating your image at different viewport sizes. The `alt` prop is used for the image's alt text. These props will be passed wherever you render your custom image components. Add the following imports and define the props that you will use in your component. You can also use TypeScript to type the props.

```astro title="src/components/MyCustomImageComponent.astro" ins={3, 11}
---
import type { ImageMetadata } from "astro";
import { getImage } from "astro:assets";

interface Props {
mobileImgUrl: string | ImageMetadata;
desktopImgUrl: string | ImageMetadata;
alt: string;
}

const { mobileImgUrl, desktopImgUrl, alt } = Astro.props;
---

```

3. Define each of your responsive images by calling the `getImage()` function with your desired properties.

```astro title="src/components/MyCustomImageComponent.astro" ins={13-18, 20-25}
---
import type { ImageMetadata } from "astro";
import { getImage } from "astro:assets";

interface Props {
mobileImgUrl: string | ImageMetadata;
desktopImgUrl: string | ImageMetadata;
alt: string;
}

const { mobileImgUrl, desktopImgUrl, alt } = Astro.props;

const mobileImg = await getImage({
src: mobileImgUrl,
format: "webp",
width: 200,
height: 200,
});

const desktopImg = await getImage({
src: desktopImgUrl,
format: "webp",
width: 800,
height: 200,
});
---

```

4. Create a `<picture>` element that generates a `srcset` with your different images based on your desired media queries.

```astro title="src/components/MyCustomImageComponent.astro" ins={28-32}
---
import type { ImageMetadata } from "astro";
import { getImage } from "astro:assets";

interface Props {
mobileImgUrl: string | ImageMetadata;
desktopImgUrl: string | ImageMetadata;
alt: string;
}

const { mobileImgUrl, desktopImgUrl, alt } = Astro.props;

const mobileImg = await getImage({
src: mobileImgUrl,
format: "webp",
width: 200,
height: 200,
});

const desktopImg = await getImage({
src: desktopImgUrl,
format: "webp",
width: 800,
height: 200,
});
---

<picture>
<source media="(max-width: 799px)" srcset={mobileImg.src} />
<source media="(min-width: 800px)" srcset={desktopImg.src} />
<img src={desktopImg.src} alt={alt} />
</picture>

```

5. Import and use `<MyCustomImageComponent />` in any `.astro` file. Be sure to pass the necessary props for generating two different images at the different viewport sizes:

```astro title="src/pages/index.astro"
---
import MyCustomImageComponent from "../components/MyCustomImageComponent.astro";
---

<MyCustomImageComponent
mobileImgUrl="/images/mobile-profile-image.jpg"
desktopImgUrl="/images/desktop-profile-image.jpg"
alt="user profile picture"
/>

```