最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Getting type errors form a snippet copied from Next.js 15 docs (opengraph-image.tsx) - Stack Overflow

programmeradmin0浏览0评论

In the Next.js 15.1.6 docs (App Router), the last code snippet on the Metadata Files: opengraph-image and twitter-image | Next.js page explains how to fetch a local image on the file system and pass it as an ArrayBuffer to the src attribute of an <img> element in order to programmatically generate an OpenGraph image (very useful for dynamic route segments).

Here is the snippet:

app/opengraph-image.tsx:

import { ImageResponse } from 'next/og'
import { join } from 'node:path'
import { readFile } from 'node:fs/promises'
 
export default async function Image() {
  const logoData = await readFile(join(process.cwd(), 'logo.png'))
  const logoSrc = Uint8Array.from(logoData).buffer
 
  return new ImageResponse(
    (
      <div
        style={{
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        }}
      >
        <img src={logoSrc} height="100" />
      </div>
    )
  )
}

When I copy and paste this snippet into a new Next.js 15 project (create-next-app@latest), I get a type error saying:

Type 'ArrayBuffer' is not assignable to type 'string'.ts(2322)

index.d.ts(3051, 9): The expected type comes from property 'src' which is declared here on type 'DetailedHTMLProps<ImgHTMLAttributes, HTMLImageElement>'

⚠ Error (TS2322) | Type ArrayBuffer is not assignable to type string.

(property) ImgHTMLAttributes.src?: string | undefined

Are the docs wrong?

Here is a reproduction repository:

You can see the type error by opening src/app/opengraph-image.tsx in a Typescript-enabled editor or by running npm run build

In the Next.js 15.1.6 docs (App Router), the last code snippet on the Metadata Files: opengraph-image and twitter-image | Next.js page explains how to fetch a local image on the file system and pass it as an ArrayBuffer to the src attribute of an <img> element in order to programmatically generate an OpenGraph image (very useful for dynamic route segments).

Here is the snippet:

app/opengraph-image.tsx:

import { ImageResponse } from 'next/og'
import { join } from 'node:path'
import { readFile } from 'node:fs/promises'
 
export default async function Image() {
  const logoData = await readFile(join(process.cwd(), 'logo.png'))
  const logoSrc = Uint8Array.from(logoData).buffer
 
  return new ImageResponse(
    (
      <div
        style={{
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        }}
      >
        <img src={logoSrc} height="100" />
      </div>
    )
  )
}

When I copy and paste this snippet into a new Next.js 15 project (create-next-app@latest), I get a type error saying:

Type 'ArrayBuffer' is not assignable to type 'string'.ts(2322)

index.d.ts(3051, 9): The expected type comes from property 'src' which is declared here on type 'DetailedHTMLProps<ImgHTMLAttributes, HTMLImageElement>'

⚠ Error (TS2322) | Type ArrayBuffer is not assignable to type string.

(property) ImgHTMLAttributes.src?: string | undefined

Are the docs wrong?

Here is a reproduction repository: https://github/shawninder/opengraph-type-error-repro

You can see the type error by opening src/app/opengraph-image.tsx in a Typescript-enabled editor or by running npm run build

Share Improve this question edited Jan 31 at 19:48 Shawn asked Jan 31 at 16:35 ShawnShawn 11.4k22 gold badges85 silver badges139 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

I got my answer after submitting a but report on GitHub.

tl;dr

The code is fine. Typescript just needs some convincing.

Explanation

The ImageResponse component uses satori to convert JSX into an image. This adds the possibility of providing an Array buffer as src for <img>s, which is not usually supported. Unfortunately, there doesn't seem to be a way for satori to let Typescript know about this without affecting JSX more generally.

As shuding explains:

this is unfortunately something Satori can't work around. If it provides a .d.ts to allow Buffer/ArrayBuffer values for img tag's src field, it will be a global TypeScript override and will affect other JSX code.

Unless TS gives us a way to affect global types of a scoped value (e.g. JSX values passed into satori(...)), there's nothing Satori can do here.

Workarounds

Thankfully, there are a few suggestions in the GitHub issues:

  1. As suggested by icyJoseph: Let typescript know everything's OK using a comment:
// @ts-expect-error Satori does support buffers as src
<img src={logoSrc} height="100" />
  1. As suggested by souporserious, use as any:
<img src={logoSrc as any} height="100" />
  1. As suggested by souporserious, convert to base64:
<img src={`data:image/png;base64,${Buffer.from(logoSrc).toString('base64')}`} height="100" />

What's Next?

icyJoseph has offered to submit a PR to improve the documentation surrounding the code snippet.

发布评论

评论列表(0)

  1. 暂无评论