Next.js (App Router) + Cloudfront + S3のデプロイ方法
はじめに
今回Next.jsは、App Routerの構成です。
静的なHTMLファイルとして出力する
next.config.mjsファイルを以下のように追記して静的エクスポートを有効にしてください。
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export', // 追記
};
export default nextConfig;
その後下記のコマンドで静的なHTMLファイルとして出力します。
npm run build
プロジェクト直下にoutというフォルダができたことを確認してください。
S3の作成
今回はCloudFrontを経由させるため、静的ウェブサイトホスティングは無効のままで問題ないです。
先ほど作成したoutというフォルダ内のものをすべてアップロードしてください。
CloudFrontの作成
ディストリビューションを作成
を選択、
Origin domainから先ほど作成したS3を選択してください。
Origin access control settings (recommended)
をチェックし、今回は新規作成するのでCreate new OAC
を選択します。
署名リクエスト (推奨)にチェックにチェックが入っていることを確認し、Create
を選択してください。
今回はPOSTもできるようにしたいので許可された HTTP メソッド
ではGET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE
を選択しました。
ウェブアプリケーションファイアウォール (WAF) ではセキュリティ保護を有効にしないでください
を選択したら下へスクロールして、右下のディストリビューションを作成
を選択してください。
下記のように表示がされると思うので、ポリシーをコピー
を選択し、S3 バケットポリシーを更新します。
S3のバケットポリシーを編集する
作成したS3に移動します。
アクセス許可 > バケットポリシー の編集
を選択し、
先ほどコピーしたポリシーを貼り付けたら、右下の変更の保存
を選択してください。
デフォルトルートオブジェクトの設定
このままではCloudFrontが提供するコンテンツにアクセスした際にドメインに/index.html
を付けないとエラーになります。
ルートディレクトリの場合はこれから説明する関数を利用してもいいのですが、CloudFrontディストリビューションの一般 > 設定で、デフォルトルートオブジェクト - オプション
をindex.html
に設定するとindex.htmlの内容を表示してくれるのでこちらの方が簡単だと思います。
ですが、サブディレクトリではこの設定ができないので関数を定義します。
サブディレクトリでデフォルトオブジェクトを設定したい場合
CloudFront > 左メニューの関数 > 関数を作成
を選択、
関数名を入力したら、 関数を作成
を選択、
関数コードに以下を貼り付け、変更を保存
を選択してください。
function handler(event) {
var request = event.request;
var uri = request.uri;
// Check whether the URI is missing a file name.
if (uri.endsWith('/')) {
request.uri += 'index.html';
}
// Check whether the URI is missing a file extension.
else if (!uri.includes('.')) {
request.uri += '/index.html';
}
return request;
}
タブから発行に移動し、関数を発行
を選択してください。
関数を発行しなかった場合に関数の紐づけを行うと、次のエラーが表示されます。
The parameter FunctionAssociationArn is invalid; add_indexhtml was not found or is not published.
関数を紐づける
作成したディストリビューションを選択し、タブでビヘイビアに移動します。対象となるものを選択したら編集
を選択してください。
下へスクロールし、関数の関連付けのビューワーリクエスト
から関数タイプCloudFront Functions
を選択、先ほど作成した関数を選択したら、変更を保存
を押してください。
アクセスの確認
CloudFront > ディストリビューションドメイン名にアクセスして表示が確認されれば問題ありません。
CloudFrontのキャッシュ削除
アップロードするファイルを変更した際は必ずCloudFrontのキャッシュ削除を行うようにしてください。
/*
参考にさせていただきました
終わりに
何かありましたらお気軽にコメント等いただけると助かります。
ここまでお読みいただきありがとうございます🎉
Discussion