Next.js App Routerでのファビコン設定
問題の背景
Next.jsのApp Routerが導入されたことで、従来のhead.js
ファイルが廃止されました。代わりにlayout.tsx
ファイル内のmetadata
オブジェクトを使ってメタデータを管理する必要があります。ファビコン(サイトのアイコン)を追加する方法が変更されたため、多くの開発者が以下のような疑問を持っています:
- ファビコンを正しく設定するにはどうすればいいか?
- PNG形式のファビコンは使えるのか?
- 複数のサイズのアイコンやAppleタッチアイコンはどう管理するか?
- ディレクトリ構成に決まりはあるのか?
基本解決策
自動認識される方法(推奨)
Next.jsは特定のファイル名のアイコンを自動認識します。最も簡単な方法は次のとおりです:
PNG/JPEG/SVGアイコンを使用:
bash# appディレクトリにアイコンファイルを直接配置 app/ icon.png # または icon.jpg, icon.svg
ICO形式のファビコンを使用:
bashapp/ favicon.ico
自動認識のルール:
ファイル名 | サポート形式 | 配置場所 |
---|---|---|
favicon.ico | .ico | app/ |
icon | .ico , .jpg , .jpeg , .png , .svg | app/**/* |
apple-icon | .jpg , .jpeg , .png | app/**/* |
ポイント:
favicon.ico
はapp/
直下のみ- 他の形式のアイコンは
icon
というプレフィックスで始まる名前にする - メタデータを手動で定義する必要はありません
手動でmetadataを定義する方法
ファイル名をカスタマイズしたい場合や複数のアイコンを設定する場合は、layout.tsx
で直接定義します:
import { Metadata } from 'next';
export const metadata: Metadata = {
title: 'サイトタイトル',
icons: {
icon: '/custom-favicon.png', // パブリックパスを指定
apple: '/apple-touch-icon.png'
}
};
複数解像度アイコンの設定
モダンなウェブサイトでは複数サイズのアイコンを提供することが推奨されます:
export const metadata: Metadata = {
icons: {
icon: [
{
url: "/favicon/favicon-16x16.png",
sizes: "16x16",
type: "image/png"
},
{
url: "/favicon/favicon-32x32.png",
sizes: "32x32",
type: "image/png"
},
{
url: "/favicon/android-chrome-192x192.png",
sizes: "192x192",
type: "image/png"
}
],
apple: {
url: "/favicon/apple-touch-icon.png",
sizes: "180x180"
}
},
manifest: "/favicon/site.webmanifest"
};
ディレクトリ構成の注意
パブリックフォルダ構成例:
public/
favicon/
favicon-16x16.png
favicon-32x32.png
android-chrome-192x192.png
apple-touch-icon.png
site.webmanifest
よくある問題と解決策
1. ファビコンが更新されない
.next/
ディレクトリを削除:bashrm -rf .next/
ブラウザのキャッシュをクリア(特にfavicon.icoはキャッシュされやすい)
2. パスの競合エラー
Error: A conflicting public file and page file was found for path /favicon.ico
重大な設定ミス
public/
とapp/
の両方にファビコンを配置しない- 重複ファイルのどちらかを削除(通常は
public/favicon.ico
を削除)
3. デフォルトファビコンの表示が続く
- 正しいファイル名を使っているか確認(
favicon.ico
かicon.*
) - 静的ファイルは
public/
直下ではなくpublic/favicon/
などサブディレクトリに配置 - 開発サーバーを再起動
高度な使用方法
パスごとに異なるアイコンを設定
App Routerのフォルダ構造を活用して、ページグループごとにアイコンを設定できます:
app/
icon.svg # デフォルトアイコン
dashboard/
icon.svg # ダッシュボード用アイコン
プログラムによるアイコン生成
動的にアイコンを生成するにはicon.tsx
ファイルを作成:
// app/[slug]/icon.tsx
import { ImageResponse } from "next/og";
export const size = { width: 32, height: 32 };
export const contentType = "image/png";
export default function Icon({ params }: { params: { slug: string } }) {
return new ImageResponse(
(
<div style={{
fontSize: 24,
background: "black",
width: "100%",
height: "100%",
display: "flex",
alignItems: "center",
justifyContent: "center",
color: "white",
borderRadius: "100%",
textTransform: "capitalize"
}}>
{params.slug[0]}
</div>
),
{ ...size }
);
}
動作条件
- ファイル名:
icon.tsx
/apple-icon.tsx
- ディレクトリ構造に応じて自動的に適用
next/og
のImageResponseを使用
ベストプラクティスまとめ
シンプルなアイコン設定にはファイル名ルールを活用
app/icon.png
かapp/favicon.ico
を配置複数解像度対応はファイルを分割
/public/favicon/
ディレクトリに格納しmetadata
で定義キャッシュ問題には
.next
ディレクトリ削除
古いキャッシュが残っていないことを確認アイコンの重複排除
public/
とapp/
の両方に置かない最新の仕様を確認する
公式App Iconsドキュメントを参照
ファビコンの設定は、Next.jsのファイルベースルーティングを理解する良い練習となります。自動認識機能を活用するか、必要な場合はmetadata
を手動設定することで、効率的にアイコン管理が可能です。