Skip to content

Next.js App Routerでのファビコン設定

問題の背景

Next.jsのApp Routerが導入されたことで、従来のhead.jsファイルが廃止されました。代わりにlayout.tsxファイル内のmetadataオブジェクトを使ってメタデータを管理する必要があります。ファビコン(サイトのアイコン)を追加する方法が変更されたため、多くの開発者が以下のような疑問を持っています:

  • ファビコンを正しく設定するにはどうすればいいか?
  • PNG形式のファビコンは使えるのか?
  • 複数のサイズのアイコンやAppleタッチアイコンはどう管理するか?
  • ディレクトリ構成に決まりはあるのか?

基本解決策

自動認識される方法(推奨)

Next.jsは特定のファイル名のアイコンを自動認識します。最も簡単な方法は次のとおりです:

  1. PNG/JPEG/SVGアイコンを使用:

    bash
    # appディレクトリにアイコンファイルを直接配置
    app/
      icon.png  # または icon.jpg, icon.svg
  2. ICO形式のファビコンを使用:

    bash
    app/
      favicon.ico

自動認識のルール:

ファイル名サポート形式配置場所
favicon.ico.icoapp/
icon.ico, .jpg, .jpeg, .png, .svgapp/**/*
apple-icon.jpg, .jpeg, .pngapp/**/*

ポイント:

  • favicon.icoapp/直下のみ
  • 他の形式のアイコンはiconというプレフィックスで始まる名前にする
  • メタデータを手動で定義する必要はありません

手動でmetadataを定義する方法

ファイル名をカスタマイズしたい場合や複数のアイコンを設定する場合は、layout.tsxで直接定義します:

tsx
import { Metadata } from 'next';

export const metadata: Metadata = {
  title: 'サイトタイトル',
  icons: {
    icon: '/custom-favicon.png', // パブリックパスを指定
    apple: '/apple-touch-icon.png'
  }
};

複数解像度アイコンの設定

モダンなウェブサイトでは複数サイズのアイコンを提供することが推奨されます:

tsx
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"
};

ディレクトリ構成の注意

パブリックフォルダ構成例:

bash
public/
  favicon/
    favicon-16x16.png
    favicon-32x32.png
    android-chrome-192x192.png
    apple-touch-icon.png
    site.webmanifest

よくある問題と解決策

1. ファビコンが更新されない

キャッシュの問題は開発中によく発生します。解決手段:
  1. .next/ディレクトリを削除:

    bash
    rm -rf .next/
  2. ブラウザのキャッシュをクリア(特にfavicon.icoはキャッシュされやすい)

2. パスの競合エラー

sh
Error: A conflicting public file and page file was found for path /favicon.ico

重大な設定ミス

  • public/app/両方にファビコンを配置しない
  • 重複ファイルのどちらかを削除(通常はpublic/favicon.icoを削除)

3. デフォルトファビコンの表示が続く

  • 正しいファイル名を使っているか確認(favicon.icoicon.*
  • 静的ファイルはpublic/直下ではなくpublic/favicon/などサブディレクトリに配置
  • 開発サーバーを再起動

高度な使用方法

パスごとに異なるアイコンを設定

App Routerのフォルダ構造を活用して、ページグループごとにアイコンを設定できます:

app/
  icon.svg          # デフォルトアイコン
  dashboard/
    icon.svg        # ダッシュボード用アイコン

プログラムによるアイコン生成

動的にアイコンを生成するにはicon.tsxファイルを作成:

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を使用

ベストプラクティスまとめ

  1. シンプルなアイコン設定にはファイル名ルールを活用
    app/icon.pngapp/favicon.ico を配置

  2. 複数解像度対応はファイルを分割
    /public/favicon/ ディレクトリに格納しmetadataで定義

  3. キャッシュ問題には.nextディレクトリ削除
    古いキャッシュが残っていないことを確認

  4. アイコンの重複排除
    public/app/の両方に置かない

  5. 最新の仕様を確認する
    公式App Iconsドキュメントを参照

ファビコンの設定は、Next.jsのファイルベースルーティングを理解する良い練習となります。自動認識機能を活用するか、必要な場合はmetadataを手動設定することで、効率的にアイコン管理が可能です。