Laravel に任意の favicon を追加する

# はじめに
以前、Laravel で作成した Web アプリケーションに favicon を追加する方法を Laravel 公式ドキュメントから参照しようとしましたが、記載がなく調べました。その備忘録としてまとめさせていただきます。

# 環境
OS: Ubuntu-20.04 (Windows 10 の WSL2 上に設置)
PHP: 8.0.10
Laravel: 8.61.0

# 事前準備
検証のために、favicon を事前に2つ作成しておきます。favicon の作成自体はフリーのサイトを用いて、PNG や JPEG を ICO 形式に変換することで可能です。

今回私は Favicon ジェネレーター様を用いました。
https://favicon-generator.mintsu-dev.com/

また、変換対象の画像としては、いらすとや様の地球儀とノートパソコンの画像を用いました。
地球儀の画像
https://www.irasutoya.com/2013/02/blog-post_3995.html

ノートパソコンの画像
https://www.irasutoya.com/2020/11/blog-post_25.html

作成した favicon は以下の通りになります。
![favicon_lists.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589635/56dd926f-efa6-99e9-e266-eec95af9c62f.png)

# 1. すべてのページに同一の favicon を設置したい場合
Laravel の Web アプリケーションすべてのページに favicon を設置したい場合は、public ディレクトリ下にある favicon.ico を、自身が作成した favicon.ico に変更することによって反映されます。

例えば、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589635/7d540a7b-690a-26ea-9c19-7552610e922a.png)
ここに設定されている favicon.ico を先ほど作成した 地球儀の favicon に変更すると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589635/c34c3eb2-136b-ce0e-c775-c7d5cd8c022a.png)
![favicon_route.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589635/a9993010-cc4c-e92f-9cc8-3cec73115a77.png)
地球儀の favicon に変更されていることを確認できます。

また、新しく"localhost/top"ページを作成してみます。

```php:routes/web.php
<?php

use App\Http\Controllers\TopController;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::get('/top', [TopController::class, 'index']);
```

```php:app/Http/Controllers/TopController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class TopController extends Controller
{
    public function index()
    {
        return view('top.index');
    }
}
```

```php:resources/views/top/index.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Top Page</title>
</head>
<body>
    <div>Hello Laravel!</div>
</body>
</html>
```
新しく作成した Top ページの favicon も地球儀の画像になっていることを確認できます。
![favicon_top_earth.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589635/c5712bd9-1975-baa5-05c3-5368b40fa1c3.png)

注意点としては、この場合に指定する画像は、"public/favicon.ico" として入れないといけないというところです。

例えば、"public/images/favicon_earth.ico" のように画像を置いても、favicon としては認識されません。

任意のディレクトリ下に favicon のファイルを置きたいときは次項のような対応が必要です。

# 2. ページごとに favicon を使い分けたいとき
このページには地球儀の画像を、別のページにはパソコンの画像を favicon として使いたいということがあるかもしれません。

もしくは、public ディレクトリの任意のディレクトリ下に、任意のファイル名の画像を favicon として用いたいということがあるかもしれません。

その場合は、HTML の head に link タグを入れることで実現可能です。

例えば、"public/images/favicon/favicon_pc.ico"として、favicon 用のパソコンの画像を入れ、パソコンの画像を、先ほど作成した Top ページの favicon にするとします。このとき、それ以外のページの favicon は、先ほど追加した地球儀の画像とします。

![favicon_pc_vscode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589635/de12c11b-608e-b429-8968-3fbd3db39691.png)

今回は、Top ページの favicon のみ PC の画像としたいため、index.blade.php の head に、public ディレクトリから任意の画像を取得して favicon として設定するための link タグを設定します。
このとき、public ディレクトリ内のファイルを読み取るために asset ヘルパを使用しています。

```php:resources/views/top/index.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <!-- 追加箇所 -->
    <link rel="icon" href="{{ asset('images/favicon/favicon_pc.ico') }}">
    <!-- 追加箇所 ここまで -->
    <title>Top Page</title>
</head>
<body>
    <div>Hello Laravel!</div>
</body>
</html>
```

再度、Top ページにアクセスすると、favicon がパソコンの画像に変わっていることを確認できます。
![favicon_pc_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589635/ac1071ed-0cdd-48f2-80a0-915597f5bcf0.png)

このように、ページごとに、かつ任意のファイル名で favicon を設定することが可能です。

現実的には、「画像の類は public ディレクトリに保管しておきたい」、「画像は AWS S3 や Azure Storage などのクラウドサービスのストレージから参照したい」などがあるため、こちらのパターンが多く使われるかと思います。

# favicon 反映の優先順位
先ほどの例を見るに、"public/favicon.ico"は入ったままのため、favicon の優先順位としては、
① public ディレクトリに入れられており、link タグでディレクトリから参照されたファイル
② public/favicon.ico
ということがわかります。

# 最後に
favicon を Laravel プロジェクトに設定するにはこれらの方法で実現可能かと思います。自身が実装したいアプリケーションや参画しているプロジェクトに応じて、これらの方法を使い分けてみてください。

# 参考元
https://readouble.com/laravel/8.x/ja/helpers.html#method-asset

https://saitoblog.page/posts/2020-12-17/

https://techacademy.jp/magazine/30972