AWS S3とCloudFrontを使ってシングルページアプリケーション(SPA)を公開する

AWSを使用してウェブサイトを公開する際、S3とCloudFrontは非常に人気のある選択肢です。これらのサービスは、静的コンテンツの配信に優れており、シングルページアプリケーション(SPA)のようなモダンなウェブアプリケーションのホスティングに適しています。しかし、S3の静的ウェブサイトホスティングとCloudFrontを組み合わせる際には、いくつかの設定を理解しておく必要があります。

S3の静的ウェブサイトホスティング

Amazon S3は、静的ウェブサイトホスティングを簡単に行えるようにサポートしています。これにより、HTML、CSS、JavaScriptファイルなどの静的ファイルを保存し、ウェブサイトとして公開できます。S3バケットで静的ウェブサイトホスティングを有効にすると、デフォルトドキュメント(通常はindex.html)へのリクエストをサポートし、特定のパスが指定された場合に自動的にそのファイルを返すようになります。これはSPAの開発において重要な機能です。なぜなら、クライアントサイドでのルーティングを使って、異なるURLが同一のHTMLファイルによって処理されることが多いからです。

例: http://example-bucket.s3-website-region.amazonaws.com/about のリクエストは、about ディレクトリにファイルが存在しなくても、自動的に index.html を返します。

CloudFrontとS3の組み合わせ

CloudFrontは、AWSが提供する高速コンテンツ配信ネットワーク(CDN)サービスで、世界中のエッジロケーションからコンテンツを迅速に配信できます。S3バケットをオリジンとしてCloudFrontディストリビューションを設定することで、ウェブサイトのロード時間を短縮し、セキュリティを強化することが可能です。

しかし、CloudFrontを介してSPAを公開する際には、S3の静的ウェブサイトホスティングとは異なる挙動に注意する必要があります。特に、存在しないパスへのリクエストが来た場合、CloudFrontはデフォルトでindex.htmlにリダイレクトせず、404エラーを返すため、SPAのクライアントサイドルーティングが期待通りに機能しません。

解決策: カスタムエラーレスポンスの設定

この問題を解決するには、CloudFrontディストリビューションのカスタムエラーレスポンス設定を使用します。具体的には、404(NotFound)や403(Forbidden)のエラーが発生した場合に、index.htmlページを返し、HTTPステータスコード200を使用してレスポンスするように設定します。これにより、リクエストされたパスに対応するファイルがS3バケットに存在しない場合でも、クライアントサイドのJavaScriptがルーティングを処理できるようになります。

AWS CDKを使用してこの設定を実装する例は以下の通りです。

const distribution = new cloudfront.Distribution(this, 'SiteDistribution', {
  // その他の設定...
  errorResponses: [
    {
      httpStatus: 404,
      responseHttpStatus: 200,
      responsePagePath: '/index.html',
      ttl: Duration.seconds(0),
    },
    {
      httpStatus: 403,
      responseHttpStatus: 200,
      responsePagePath: '/index.html',
      ttl: Duration.seconds(0),
    }
  ],
});

この設定により、CloudFrontはS3と同様の挙動をするようになり、SPAのホスティングに適した環境を提供します。

結論

AWS S3とCloudFrontは、静的コンテンツやSPAの公開に強力な選択肢です。ただし、CloudFrontを介してSPAを公開する場合には、カスタムエラーレスポンスの設定を適切に行うことで、クライアントサイドルーティングを正しく機能させることが可能になります。この設定により、ユーザーにとってより快適なウェブサイト体験を提供することができます。