Amplifyでテキストファイルを配信しようとしたら文字化けしたのでContent-Typeを指定してみた

Amplifyなら簡単にカスタムヘッダーを設定できますよ!

こんにちは。枡川です。

Amplifyでテキストファイルを配信しようとしたら文字化けしたので対処方法を残しておきます。
Content-Typeを指定するのみにはなるのですが、単純にS3とCloudFrontで静的サイトを構築した場合とは大分勝手が異なりました。
S3とCloudFrontの場合は、下記記事で紹介されているようにCloudFront Functionを使用することが可能ですし、s3 syncのオプションを使用してContent-Typeを指定しておくことも可能です。

一方、Amplifyの場合は独自のカスタムヘッダー機能を用いて設定することとなります。

テキストファイルを配信したら文字化けした

下記のようにhtmlファイルとテキストファイルが混在したディレクトリを使ってAmplifyアプリを作成し、Google Chromeでアクセスを試みました。

tree .
.
├── index.html
├── test-sjis.txt(Shift-JISでエンコーディング)
├── test-utf8.txt(UTF-8でエンコーディング)
└── txt
    └── test-utf8.txt(UTF-8でエンコーディング)

カスタムヘッダーを特に設定しなくてもindex.htmlは正しく表示されます。
一方、test-utf8.txt(UTF-8でエンコーディング)は正しく表示されずに下記のように文字化けしました。

Shift-JISでエンコーディングしたファイル(test-sjis.txt)は正しく表示されたので、Google Chromeのデフォルト設定ではテキストファイルをすべてShift-JISと判別して表示してしまっているようです。

curlで確認してみると、htmlファイルでも文字コードは設定されていません。

curl -I https://main.dcrgjecixfnnz.amplifyapp.com/
HTTP/2 200
content-type: text/html
==================== 省略 ====================

テキストファイルでも文字コードが設定されていない状態です。

curl -I https://main.dcrgjecixfnnz.amplifyapp.com/test-utf8.txt
HTTP/2 200
content-type: text/plain
==================== 省略 ====================

カスタムヘッダーの設定

Amplifyの機能を使用してContent-Typeを設定していきます。
Amplifyアプリのアプリの設定からカスタムヘッダーへ移動します。
カスタムヘッダーの仕様を編集して、保存をクリックします。
htmlファイルの場合はmeta要素で文字コードを指定したりもできますが、ついでにhtmlファイルについても設定しておきます。

customHeaders:
  - pattern: '**/*.txt'
    headers:
      - key: Content-Type
        value: 'text/plane; charset=UTF-8'
  - pattern: '**/*.html'
    headers:
      - key: Content-Type
        value: 'text/html; charset=UTF-8'

その他のカスタムヘッダも同様に設定可能です。
カスタムヘッダー設定については下記リンク先に記載があります。

設定後すぐに反映された表示がでます。
文字化けが解消されない場合はキャッシュが残っている可能性が高いです。
Google Chromeでは履歴 > 閲覧履歴データの削除からキャッシュを削除することで文字化けが解消されると思われます。
それでもだめならアプリを再デプロイすれば解消されるはずです。

curlでも確認してみました。
index.htmlについて、エンコーディングがUTF-8として設定されています。

curl -I https://main.dcrgjecixfnnz.amplifyapp.com
HTTP/2 200
content-type: text/html; charset=UTF-8
==================== 省略 ====================

テキストファイルについても文字コードが設定されるようになりました。

curl -I https://main.dcrgjecixfnnz.amplifyapp.com/test-utf8.txt
HTTP/2 200
content-type: text/plane; charset=UTF-8
==================== 省略 ====================

階層があっても正しく反映されています。

curl -I https://main.dcrgjecixfnnz.amplifyapp.com/txt/test-utf8.txt
HTTP/2 200
content-type: text/plane; charset=UTF-8
==================== 省略 ====================

まとめ

Amplifyだと背後にいるS3やCloudFrontの設定が見えづらいですが、基本的なことはきちんとできるようになっています。
この手軽にできる感じが良いですね!