Reputation: 905
I am using the new @vercel/og library to generate the metatag image. From the official example, they showed how to use image from external source.
<img
src={"https://res.cloudinary.com/iqfareez-cloud/image/upload/v1665576747/IIUM%20Schedule/release_meta_kosong_onkkbm.png"}
alt={"Release background"}
>
However, I want to use the local static image stored in the public directory public/images/release-bg.png
. This guide shows an example to access the static assets so I tried it like this:
<Image
src={"/images/release-bg.png"}
alt={"Release background"}
>
Then, I get this warning:
Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
Followed by this error:
code: 'ERR_UNHANDLED_ERROR',
context: TypeError: Cannot read properties of null (reading 'useContext')
at Object.useContext (webpack-internal:///(middleware)/./node_modules/react/cjs/react.development.js:1619:21)
at Object.Image [as type] (webpack-internal:///(middleware)/./node_modules/next/dist/client/image.js:38:39)
at gt (webpack-internal:///(middleware)/./node_modules/satori/dist/esm/index.wasm.js:18:17771)
etc...
// /pages/api/og/iiumschedule.tsx
import {ImageResponse} from '@vercel/og';
import {NextRequest} from 'next/server';
import Image from 'next/image';
export const config = {
runtime: 'experimental-edge',
};
export default async function handler(req: NextRequest) {
const {searchParams} = req.nextUrl;
const version = searchParams.get('version');
if (!version) {
return new ImageResponse(<>Visit with "?username=vercel"</>, {
width: 1200,
height: 630,
});
}
return new ImageResponse(
(
<div
style={{
display: 'flex',
fontSize: 60,
color: 'black',
background: '#f6f6f6',
width: '100%',
height: '100%',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Image
src={"/images/release-bg.png"}
alt={"Release background"}
>
<p>github.com/{version}</p>
</Image>
</div>
),
{
width: 1200,
height: 628,
},
);
}
Upvotes: 0
Views: 2720
Reputation: 1675
Because the API runs on the server side, you can't fetch relative URLs (e.g. /path) because the server itself doesn't know about the domain.
You can pass https://my-domain.com/imagepath.png
instead.
Also, there is a way to directly bundle inside the API using the same way of font importing, so you don't need to fetch something again on the fly. However if you do that with an image, you will have to convert that ArrayBuffer into inlined base64 data URI and use that as the <img>
source. I think Satori will support using ArrayBuffer as the source in the future.
Upvotes: 2
Reputation: 240
<Image
src={"/images/release-bg.png"}
alt={"Release background"}
>
<p>github.com/{version}</p>
</Image>
The next.js image function component uses hooks under the hood: https://github.com/vercel/next.js/blob/canary/packages/next/client/image.tsx#L585
You should use the img element as per documentation: https://vercel.com/docs/concepts/functions/edge-functions/og-image-examples
Upvotes: 0