💭
【Next.js】外部サイトのOGPを取得する方法
はじめに
Next.jsで開発をしていた時にOGPを取得する用途があり、調べたのでまとめました。
OGPとは
OGPとは、Open Graph Protocol の略で、ウェブサイトのコンテンツをソーシャルメディア(LINEやFacebookやXなど)で共有する際に、どのように表示されるかを指定するためのプロトコルです。
ソーシャルメディアでリンクとして共有されたときに、タイトル、画像、説明文などをカスタマイズすることで、視覚的にリッチなプレビューを提供できます。
この記事ではOGPの取得、つまりURLからその外部ウェブサイトのコンテンツ情報(タイトル、説明、画像など)を取得する方法を説明します。
OGP取得手順
ZennのURLhttps://zenn.dev/
から取得できるOGPは以下です。
{
"success": true,
"twitterCard": "summary",
"ogUrl": "https://zenn.dev",
"ogTitle": "Zenn|エンジニアのための情報共有コミュニティ",
"ogDescription": "Zennはエンジニアが技術・開発についての知見をシェアする場所です。本の販売や、読者からのバッジの受付により対価を受け取ることができます。",
"ogType": "article",
"ogSiteName": "Zenn",
"ogImage": [
{
"url": "https://static.zenn.studio/images/logo-only-dark.png",
"type": "png"
}
],
"ogLocale": "ja",
"ogDate": "2024-09-19T13:41:18+00:00",
"favicon": "https://static.zenn.studio/images/logo-transparent.png",
"charset": "utf-8",
"requestUrl": "https://zenn.dev/"
}
1.外部ライブラリのインストール
OGP情報の解析を簡単に行うために、open-graph-scraper
ライブラリを使用します。
npm install open-graph-scraper
2.OGP取得関数を作成
lib/getOgp.ts
import ogs from "open-graph-scraper";
export async function getOgp(url: string) {
try {
const { result } = await ogs({ url });
return result;
} catch (error) {
console.error("Error fetching OGP:", error);
return null;
}
}
3.OGP取得
サーバーサイドでOGPを取得します。どちらでも可能です。
- ①Server Components内で取得
- ②Server Actions内で取得
①Server Components内で取得
以下はServer Components内で取得する例です。
page.tsx
import { getOgp } from "@/lib/getOgp";
export default async function Page() {
const ogp = await getOgp("https://zenn.dev/");
return (
<div>
{ogp && (
<div className="mb-6 max-w-md rounded-lg bg-white p-4 shadow-md">
<h2 className="mb-2 text-xl font-semibold">
{ogp?.ogTitle ?? "No Title"}
</h2>
<p className="mb-4">{ogp?.ogDescription}</p>
<div className="mb-4 flex">
{ogp?.ogImage && ogp?.ogImage.length > 0 && (
<img
src={ogp?.ogImage[0]?.url}
alt={ogp?.ogImage[0]?.alt ?? "OGP Image"}
className="mb-2 h-auto w-48"
/>
)}
</div>
</div>
)}
</div>
);
}
②Server Actions内で取得
フォームにURLを追加してボタンを押した時にOGPを取得するようなユーザーのインタラクティブな操作がある場合はServer Actions内で処理を行います。
以下はServer Actionsで使用する例です。
lib/ogpActions.ts
"use server";
import { OgObject } from "open-graph-scraper/types";
import { z } from "zod";
import { getOgp } from "./getOgp";
const FormSchema = z.object({
url: z.string(),
});
export async function ogpAction(
prevState: OgObject | null,
formData: FormData,
) {
const { url } = FormSchema.parse({
url: formData.get("url"),
});
try {
const result = await getOgp(url);
return result;
} catch (error) {
console.error("Error fetching OGP:", error);
return null;
}
}
Client ComponentsではuseFormState
を使ってServer ActionsからOGPを受け取って表示します。
page.tsx
"use client";
import { ogpAction } from "@/lib/ogpAction";
import React from "react";
import { useFormState } from "react-dom";
export const UrlBox = () => {
const [ogp, ogpActionState] = useFormState(ogpAction, null);
return (
<section>
<form
action={ogpActionState}
className="relative mb-6 flex w-full max-w-md items-center"
>
{/* 入力フィールド */}
<input
type="text"
name="url"
placeholder="URLを入力"
className="w-full rounded-full border border-gray-300 bg-white px-6 py-3 pr-12 text-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-400"
/>
{/* ボタン */}
<button type="submit">追加</button>
</form>
<div>
{ogp && (
<div className="mb-6 max-w-md rounded-lg bg-white p-4 shadow-md">
<h2 className="mb-2 text-xl font-semibold">
{ogp?.ogTitle ?? "No Title"}
</h2>
<p className="mb-4">{ogp?.ogDescription}</p>
<div className="mb-4 flex">
{ogp?.ogImage && ogp?.ogImage.length > 0 && (
<img
src={ogp?.ogImage[0]?.url}
alt={ogp?.ogImage[0]?.alt ?? "OGP Image"}
className="mb-2 h-auto w-48"
/>
)}
</div>
</div>
)}
</div>
</section>
);
};
まとめ
外部サイトのOGPを取得する機会があるかはわかりませんが簡単にまとめてみました。
ただいま個人開発を進めているので次回は完成次第その紹介の記事を書きたい所存!💦
Discussion