AWS AmplifyでhostingしたNext.jsのSPAが「403 Access Denied」となったときの対処法

Next.jsでSPAを作成してAWS Amplifyでhostingを試みたところ「403 Access Denied」が表示されました。
![Mozilla_Firefox.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/1dc862a3-7cd8-e51b-0ad8-6b91c889fdfd.png)
原因と対処法をまとめます。

## 再現手順

Next.jsのアプリケーションは予め作成されており、Githubにpush済みであることを前提とします。

以下コマンドを実行して、プロジェクトを初期化します。

```bash
$ amplify init
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project next-app
? Enter a name for the environment production
? Choose your default editor: Visual Studio Code
? Choose the type of app that you\'re building javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path:  src
? Distribution Directory Path: build
? Build Command:  npm run-script build
? Start Command: npm run-script start
```

以下コマンドを実行して、hostingを追加します。

```bash
$ amplify add hosting
? Select the plugin module to execute Hosting with Amplify Console (Managed hosting with custom domains, Continuous deployment)
? Choose a type Continuous deployment (Git-based deployments)
? Continuous deployment is configured in the Amplify Console. Please hit enter once you connect your repository
```

Amplify Consoleの画面がブラウザで開くので、Github認証をしてデプロイ対象を選択します。
リポジトリとブランチの選択以外はデフォルトのままです。

デプロイが完了して、デプロイ先のURLにアクセスすると「403 Access Denied」が表示されます。
![Mozilla_Firefox.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/1dc862a3-7cd8-e51b-0ad8-6b91c889fdfd.png)
## なにがいけなかったのか？

Next.jsを静的HTMLにエクスポートできていないことと、エクスポート先のディレクトリを指定できていないことが原因です。

ハマリポイントは3点あります。

### 1. package.json に記載されているbuildコマンドに静的HTMLへのエクスポートコマンドが含まれていない

`create-next-app` で自動生成された `package.json` をそのまま使用していたのですが、 `build` のコマンドが `next build` のみとなっています。

`next build` コマンドは `.next` ディレクトリにハイブリッドページの起動を前提としたファイルをビルドするだけなので、静的HTMLは出力してくれません。
`build` のコマンドに `next export` を追加することで、`out` ディレクトリに静的HTMLを出力するようになります。

```json:package.json
{
  // 省略
  "scripts": {
    "dev": "next",
    "build": "next build && next export", // 修正
    "start": "next start",
    "post-update": "echo \"codesandbox preview only, need an update\" && yarn upgrade --latest"
  }
}
```

加えて `.gitignore` に `out` を追記しておきましょう。

```bash
echo "out\n" >> .gitignore
```

### 2. amplify initしたときのDistribution Directory Pathが誤っている

`amplify init` したときの選択肢「Distribution Directory Path」にデフォルトである `build` をそのまま入力していました。
`next export` コマンドは `out` ディレクトリに静的HTMLを出力するのでこのディレクトリを指定する必要があります。

```bash
$ amplify init
Note: It is recommended to run this command from the root of your app directory
? Enter a name for the project next-app
? Enter a name for the environment production
? Choose your default editor: Visual Studio Code
? Choose the type of app that you\'re building javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path:  src
? Distribution Directory Path: out # 修正
? Build Command:  npm run-script build
? Start Command: npm run-script start
```

### 3. amplify hostingしたときのビルドの設定が誤っている(Continuous deployment を選択したときのみ該当)

Amplify ConsoleでContinuous deploymentの設定をするときに、アプリのビルド設定が自動検出されるのですが、ここのディレクトリ指定も `build` となっています。
静的HTMLの出力先である `out` に修正しましょう。

![AWS_Amplify_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/e7091a10-2ba0-1b6f-158b-095e47b1148c.png)

## 動作確認

以上3点を修正して、再度デプロイしたところ無事にSPAが表示されました :tada: 
![My_page.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/e79bacf2-d6f5-f098-2b6f-9105ea62e565.png)