はじめに
先日、Nuxt.js / S3 / CloudFront で Jamstack なサイトを作っていると、/XXX/favicon.ico is not found
が発生。
うん?
favicon.ico はルートにしか置いてないよ... 🌝
ということで、Lambda@Edge でリクエストを操作して、/XXX/favicon.ico -> /favicon.ico
にリダイレクトされるように対応しました。
コード
ちなみに、下記のコードは Classmethod さんのコチラの記事を大いに参考にしています 🍻
1exports.lambdaHandler = async (event, context, callback) => {
2 // CloudFrontのイベントからリクエストを抽出
3 let request = event.Records[0].cf.request;
4
5 const oldUri = request.uri; // リクエストから変換前のURI
6 const newUri = redirectUri(oldUri); // 変換条件からURIを変更
7
8 // リクエストに変換後のURLを注入
9 request.uri = newUri;
10
11 return callback(null, request);
12};
13
14const redirectUri = (uri) => {
15 // favicon.ico はルートディレクトリにして返す
16 if (uri.indexOf("favicon.ico") !== -1) {
17 return "/favicon.ico";
18 }
19
20 // pathの末端が拡張子付きである場合は、そのまま返す
21 if (uri.split("/").pop().search(/\./) !== -1) {
22 return uri;
23 }
24
25 // 末尾に'/'がない場合は、'/index.html'を追加
26 if (uri.search(/\/$/) === -1) {
27 return uri + "/index.html"; // 末尾に'/'を追加
28 }
29
30 // 末尾が'/'の場合、つまり、'/xxx/' -> '/xxx/index.html' に変換
31 if (uri.search(/\/$/) !== -1) {
32 return uri + "index.html"; // 末尾に'index.html'を追加
33 }
34
35 return uri;
36};
favicon.ico 対応意外にも、/XXX -> /XXX/index.html
など幾つか細かい対応をしています。