275 lines
7.3 KiB
Markdown
275 lines
7.3 KiB
Markdown
|
|
---
|
||
|
|
title: generateImageMetadata
|
||
|
|
description: Learn how to generate multiple images in a single Metadata API special file.
|
||
|
|
related:
|
||
|
|
title: Next Steps
|
||
|
|
description: View all the Metadata API options.
|
||
|
|
links:
|
||
|
|
- app/api-reference/file-conventions/metadata
|
||
|
|
---
|
||
|
|
|
||
|
|
You can use `generateImageMetadata` to generate different versions of one image or return multiple images for one route segment. This is useful for when you want to avoid hard-coding metadata values, such as for icons.
|
||
|
|
|
||
|
|
## Parameters
|
||
|
|
|
||
|
|
`generateImageMetadata` function accepts the following parameters:
|
||
|
|
|
||
|
|
#### `params` (optional)
|
||
|
|
|
||
|
|
An object containing the [dynamic route parameters](/docs/app/api-reference/file-conventions/dynamic-routes) object from the root segment down to the segment `generateImageMetadata` is called from.
|
||
|
|
|
||
|
|
```tsx filename="icon.tsx" switcher
|
||
|
|
export function generateImageMetadata({
|
||
|
|
params,
|
||
|
|
}: {
|
||
|
|
params: { slug: string }
|
||
|
|
}) {
|
||
|
|
// ...
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
```jsx filename="icon.js" switcher
|
||
|
|
export function generateImageMetadata({ params }) {
|
||
|
|
// ...
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
| Route | URL | `params` |
|
||
|
|
| ------------------------------- | ----------- | ------------------------- |
|
||
|
|
| `app/shop/icon.js` | `/shop` | `undefined` |
|
||
|
|
| `app/shop/[slug]/icon.js` | `/shop/1` | `{ slug: '1' }` |
|
||
|
|
| `app/shop/[tag]/[item]/icon.js` | `/shop/1/2` | `{ tag: '1', item: '2' }` |
|
||
|
|
|
||
|
|
## Returns
|
||
|
|
|
||
|
|
The `generateImageMetadata` function should return an `array` of objects containing the image's metadata such as `alt` and `size`. In addition, each item **must** include an `id` value which will be passed as a promise to the props of the image generating function.
|
||
|
|
|
||
|
|
| Image Metadata Object | Type |
|
||
|
|
| --------------------- | ----------------------------------- |
|
||
|
|
| `id` | `string` (required) |
|
||
|
|
| `alt` | `string` |
|
||
|
|
| `size` | `{ width: number; height: number }` |
|
||
|
|
| `contentType` | `string` |
|
||
|
|
|
||
|
|
```tsx filename="icon.tsx" switcher
|
||
|
|
import { ImageResponse } from 'next/og'
|
||
|
|
|
||
|
|
export function generateImageMetadata() {
|
||
|
|
return [
|
||
|
|
{
|
||
|
|
contentType: 'image/png',
|
||
|
|
size: { width: 48, height: 48 },
|
||
|
|
id: 'small',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
contentType: 'image/png',
|
||
|
|
size: { width: 72, height: 72 },
|
||
|
|
id: 'medium',
|
||
|
|
},
|
||
|
|
]
|
||
|
|
}
|
||
|
|
|
||
|
|
export default async function Icon({ id }: { id: Promise<string | number> }) {
|
||
|
|
const iconId = await id
|
||
|
|
return new ImageResponse(
|
||
|
|
(
|
||
|
|
<div
|
||
|
|
style={{
|
||
|
|
width: '100%',
|
||
|
|
height: '100%',
|
||
|
|
display: 'flex',
|
||
|
|
alignItems: 'center',
|
||
|
|
justifyContent: 'center',
|
||
|
|
fontSize: 88,
|
||
|
|
background: '#000',
|
||
|
|
color: '#fafafa',
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
Icon {iconId}
|
||
|
|
</div>
|
||
|
|
)
|
||
|
|
)
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
```jsx filename="icon.js" switcher
|
||
|
|
import { ImageResponse } from 'next/og'
|
||
|
|
|
||
|
|
export function generateImageMetadata() {
|
||
|
|
return [
|
||
|
|
{
|
||
|
|
contentType: 'image/png',
|
||
|
|
size: { width: 48, height: 48 },
|
||
|
|
id: 'small',
|
||
|
|
},
|
||
|
|
{
|
||
|
|
contentType: 'image/png',
|
||
|
|
size: { width: 72, height: 72 },
|
||
|
|
id: 'medium',
|
||
|
|
},
|
||
|
|
]
|
||
|
|
}
|
||
|
|
|
||
|
|
export default async function Icon({ id }) {
|
||
|
|
const iconId = await id
|
||
|
|
return new ImageResponse(
|
||
|
|
(
|
||
|
|
<div
|
||
|
|
style={{
|
||
|
|
width: '100%',
|
||
|
|
height: '100%',
|
||
|
|
display: 'flex',
|
||
|
|
alignItems: 'center',
|
||
|
|
justifyContent: 'center',
|
||
|
|
fontSize: 88,
|
||
|
|
background: '#000',
|
||
|
|
color: '#fafafa',
|
||
|
|
}}
|
||
|
|
>
|
||
|
|
Icon {iconId}
|
||
|
|
</div>
|
||
|
|
)
|
||
|
|
)
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Image generation function props
|
||
|
|
|
||
|
|
When using `generateImageMetadata`, the default export image generation function receives the following props:
|
||
|
|
|
||
|
|
#### `id`
|
||
|
|
|
||
|
|
A promise that resolves to the `id` value from one of the items returned by `generateImageMetadata`. The `id` will be a `string` or `number` depending on what was returned from `generateImageMetadata`.
|
||
|
|
|
||
|
|
```tsx filename="icon.tsx" switcher
|
||
|
|
export default async function Icon({ id }: { id: Promise<string | number> }) {
|
||
|
|
const iconId = await id
|
||
|
|
// Use iconId to generate the image
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
```jsx filename="icon.js" switcher
|
||
|
|
export default async function Icon({ id }) {
|
||
|
|
const iconId = await id
|
||
|
|
// Use iconId to generate the image
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### `params` (optional)
|
||
|
|
|
||
|
|
A promise that resolves to an object containing the [dynamic route parameters](/docs/app/api-reference/file-conventions/dynamic-routes) from the root segment down to the segment the image is colocated in.
|
||
|
|
|
||
|
|
```tsx filename="icon.tsx" switcher
|
||
|
|
export default async function Icon({
|
||
|
|
params,
|
||
|
|
}: {
|
||
|
|
params: Promise<{ slug: string }>
|
||
|
|
}) {
|
||
|
|
const { slug } = await params
|
||
|
|
// Use slug to generate the image
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
```jsx filename="icon.js" switcher
|
||
|
|
export default async function Icon({ params }) {
|
||
|
|
const { slug } = await params
|
||
|
|
// Use slug to generate the image
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Examples
|
||
|
|
|
||
|
|
#### Using external data
|
||
|
|
|
||
|
|
This example uses the `params` object and external data to generate multiple [Open Graph images](/docs/app/api-reference/file-conventions/metadata/opengraph-image) for a route segment.
|
||
|
|
|
||
|
|
```tsx filename="app/products/[id]/opengraph-image.tsx" switcher
|
||
|
|
import { ImageResponse } from 'next/og'
|
||
|
|
import { getCaptionForImage, getOGImages } from '@/app/utils/images'
|
||
|
|
|
||
|
|
export async function generateImageMetadata({
|
||
|
|
params,
|
||
|
|
}: {
|
||
|
|
params: { id: string }
|
||
|
|
}) {
|
||
|
|
const images = await getOGImages(params.id)
|
||
|
|
|
||
|
|
return images.map((image, idx) => ({
|
||
|
|
id: idx,
|
||
|
|
size: { width: 1200, height: 600 },
|
||
|
|
alt: image.text,
|
||
|
|
contentType: 'image/png',
|
||
|
|
}))
|
||
|
|
}
|
||
|
|
|
||
|
|
export default async function Image({
|
||
|
|
params,
|
||
|
|
id,
|
||
|
|
}: {
|
||
|
|
params: Promise<{ id: string }>
|
||
|
|
id: Promise<number>
|
||
|
|
}) {
|
||
|
|
const productId = (await params).id
|
||
|
|
const imageId = await id
|
||
|
|
const text = await getCaptionForImage(productId, imageId)
|
||
|
|
|
||
|
|
return new ImageResponse(
|
||
|
|
(
|
||
|
|
<div
|
||
|
|
style={
|
||
|
|
{
|
||
|
|
// ...
|
||
|
|
}
|
||
|
|
}
|
||
|
|
>
|
||
|
|
{text}
|
||
|
|
</div>
|
||
|
|
)
|
||
|
|
)
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
```jsx filename="app/products/[id]/opengraph-image.js" switcher
|
||
|
|
import { ImageResponse } from 'next/og'
|
||
|
|
import { getCaptionForImage, getOGImages } from '@/app/utils/images'
|
||
|
|
|
||
|
|
export async function generateImageMetadata({ params }) {
|
||
|
|
const images = await getOGImages(params.id)
|
||
|
|
|
||
|
|
return images.map((image, idx) => ({
|
||
|
|
id: idx,
|
||
|
|
size: { width: 1200, height: 600 },
|
||
|
|
alt: image.text,
|
||
|
|
contentType: 'image/png',
|
||
|
|
}))
|
||
|
|
}
|
||
|
|
|
||
|
|
export default async function Image({ params, id }) {
|
||
|
|
const productId = (await params).id
|
||
|
|
const imageId = await id
|
||
|
|
const text = await getCaptionForImage(productId, imageId)
|
||
|
|
|
||
|
|
return new ImageResponse(
|
||
|
|
(
|
||
|
|
<div
|
||
|
|
style={
|
||
|
|
{
|
||
|
|
// ...
|
||
|
|
}
|
||
|
|
}
|
||
|
|
>
|
||
|
|
{text}
|
||
|
|
</div>
|
||
|
|
)
|
||
|
|
)
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Version History
|
||
|
|
|
||
|
|
| Version | Changes |
|
||
|
|
| --------- | --------------------------------------------------------------------------------------------------- |
|
||
|
|
| `v16.0.0` | `id` passed to the Image generation function is now a promise that resolves to `string` or `number` |
|
||
|
|
| `v16.0.0` | `params` passed to the Image generation function is now a promise that resolves to an object |
|
||
|
|
| `v13.3.0` | `generateImageMetadata` introduced. |
|