Next.jsで、faviconを動的に設定する方法
投稿日: 2024年11月18日
ShiftBのポータルサイトに、生徒さん毎のプロフィールページを作成中です。
任意で公開できるようにし、
作成したオリジナルアプリ
執筆したブログ記事
経歴(機能開発中)
実務実績記録(機能開発中)
を自動でまとめて、転職活動や案件獲得時に、このページを見せるだけで、スクール内での活動がすべて見れるようにできればと思っています。
将来的には、ShiftBの認定パートナー的な制度も作り、パートナーの方にはバッジの付与、トークンの付与などもして、より生徒さんのブランディングに活かせていければと思っております。
さて本題ですが、上記のページは shiftb.dev/u/{slug}
という動的なURLに作ることになります。
例えば僕の場合は、shiftb.dev/u/bube.code
みたいなイメージです。
まだ途中ですが以下のようなページになる予定で、
faviconについても、ユーザーのアイコンを適用したいなと思いました。
Next.jsには、ページ毎に動的にfaviconを切り替える機能も備わっており、
とても簡単で、対象のページのディレクトリに、icon.tsx
というファイルを置くだけです。これにより、Next.jsが認識してくれ、faviconを設置できます。
今回は/u/{slug}
というパスでfaviconを動的に変更したいので、
src/app/u/[slug]/icon.tsx
を作成するだけです。
icon.tsx
の書き方も、Next.jsのルールに沿って書くだけで、実際のファイルが以下になります。
import { ImageResponse } from "next/og";
import { Profile } from "@/app/api/public/users/[slug]/route";
// Route segment config
export const runtime = "edge";
// Image metadata
export const size = {
width: 32,
height: 32,
};
export const contentType = "image/png";
interface Props {
params: {
slug: string;
};
}
export default async function Icon({ params: { slug } }: Props) {
const res = await fetch(
`${process.env.NEXT_PUBLIC_APP_BASE_URL}/api/public/users/${slug}`,
{ next: { revalidate: 60 } }
);
const data: { user: Profile } = await res.json();
const { iconUrl } = data.user;
return new ImageResponse(
(
<div
style={{
fontSize: 24,
borderRadius: "50%",
width: "100%",
height: "100%",
display: "flex",
alignItems: "center",
justifyContent: "center",
color: "#333",
}}
>
{iconUrl ? (
// eslint-disable-next-line @next/next/no-img-element
<img
src={iconUrl}
height={50}
width={50}
alt="favicon"
className="rounded-full"
/>
) : (
<span>🐈⬛</span>
)}
</div>
),
{
...size,
}
);
}
export default async function Icon
でImageResponse
をexportすることで、Next.jsに対してfaviconとして認識させることができる
Icon
関数の引数でページのパラメータ(slug
)を受け取れるので、それを元に、APIでユーザー情報を取得
ユーザーのiconUrl
を、imgタグのsrc
に設定
これだけで、完了です。
設定することができました。
ユーザー認証が必要なページのみのアプリの場合はこういった出しわけは不要と思いますが、
より個人のブランディングに生かしたいようなpublicはページを含む場合、こういった機能も活かせると良さそうです。