
リンクカードのOGP表示を next/image にする
前回リンクカードのコンポーネントを作ったのですが、そのときは普通に HTML の img
要素を使ってました。
ですが、これを Copilot にレビューしてもらったところ、今回のように外部の画像を src に指定する場合は、画像をプロキシしたり、 next/image
を使ったほうがよいとのことでしたので、今回はここを修正していきます。
前回:
next/image に切り替える
next/image は Next.js 組み込みの画像コンポーネントで、画像の最適化や管理を用意にするための様々な仕組みが用意されています。
img
とプロパティも似ているので、付替えも比較的容易かなとおもいます。
ということで、早速差し替えます。
+import Image from 'next/image'
// ... 中略
-<img
+<Image
className={styles['link-card-thumbnail--image']}
+ fill
sizes="(max-width: 768px) 120px, 320px"
src={siteMeta.image}
alt={siteMeta.title || ''}
/>
next/image
は必ず width
と height
の指定が必要なのですが今回、画像のサイズが不明1なので、fill
を使うのと、width/height
の代わりに sizes
の指定を行います(省略した場合は 100vw
を指定したものとして扱われるみたいです)。
Invalid src prop on next/image
エラー
さて、これで img
から Image
に切り替わったのですが、読み込もうとすると次のようにエラーになってしまいました。
Runtime Error
Invalid src prop (https://no7.space/blog/01K41A4QYX2Q2XRE6ZH6JPQEKC/og.png) on `next/image`, hostname "no7.space" is not configured under images in your `next.config.js`
See more info: https://nextjs.org/docs/messages/next-image-unconfigured-host
これは、next/image
で外部のリソースを表示する場合、事前に許可されたホストの画像意外読み込まないようになっているためみたいです。
で、これを解消するためには、next.config.ts
で許可リストを作ればOKです。
ただ、今回のブログコンテンツなど、参考記事のリンクカードを作る場合、リンク先全てのホストを指定するのはあまり現実的じゃありません。
なので、今回はワイルドカード指定をしてしまうことにしました。2
(一応、プロトコルは https
限定ですが、ほかは全て許容しています)
const nextConfig: NextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: '**',
port: '',
pathname: '/**',
},
],
},
}
そしたら当然ツッコミが入りました。
CSS 調整
最後に、スタイルを少し調整します。
まず、Image
コンポーネントに object-fit: cover;
を指定します。
あと、fill にしたら、 position: absolute;
がついてページ上部に全部張り付いちゃったので、親要素に position: relative
もつけました。
.link-card {
&-thumbnail {
width: $thumbnail-width;
position: relative;
&--image {
object-fit: cover;
}
}