はじめに
タイトルの件で少し詰まったので、同じ問題で困っている方への一助となれば幸いです。
状況
最近流行り?のSSGであるAstro(今回利用したテンプレートはastro-paper)をs3にデプロイした際に、s3で指定したドキュメントルート(index.html)ではページが表示できているのですが、他のページに移動した際にAccessDeniedとなり、期待する動作ができませんでした。
原因
遷移した先のパスが違いました。
そのため別途設定が必要でした。
Astroではbuildした際に/dist
配下に静的ページ表示用のhtmlファイルが出力されるのですが、そちらのディレクトリ構成を把握できていませんでした。
/dist
以下のディレクトリ構成は以下のようになります。
├── index.html
└── posts
├── 1
│ └── index.html
├── hazimemashite
│ └── index.html
└── index.html
※対象の部分を抜粋
今回意図する動作として最上位の階層のindex.html
からhazimemashite
ディレクトリ内のindex.html
のページへと遷移したいといった感じです。
実際に遷移した際のパスは
任意のドメイン名(またはCloudFrontのドメイン)/posts/hazimemashite/
となっており、hazimemashite
ディレクトリ内のindex.html
を参照できていませんでした。
実際に
任意のドメイン名(またはCloudFrontのドメイン)/posts/hazimemashite/index.html
とすると期待するページを表示できました。
しかし遷移するたびに手動でindex.html
を付け足すのはユーザビリティが最悪なので(笑)、、、
Astroのドキュメントに以下の方法がありました。
解決方法
CloudFront Functionsの実装でした。
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;
}
※ ドキュメントより引用
コードに関しては説明するまでもないですが、ユーザより/
または.
でパスのリクエストがあった際に参照するファイルは/
または.
以降のindex.html
のファイルにするよとういうものです。
私はTerraFormでAWSリソースを管理していたため以下のように実装を進めました。
# CloudFront Functionsリソースを定義
resource "aws_cloudfront_function" "astrofunction" {
name = "redirect"
runtime = "cloudfront-js-1.0"
comment = "redirect function"
publish = true
# 今回astrofunction.jsは./src内に配置しました
code = file("./src/astrofunction.js")
}
resource "aws_cloudfront_distribution" "cozycozy-blog" {
〜
default_cache_behavior {
# default_cache_behavior内に関数を付与するコード追加
function_association {
event_type = "viewer-request"
function_arn = aws_cloudfront_function.astrofunction.arn
}
}
〜
}
以上のコードを記述後terraform apply
を問題なくリソースを更新後、
任意のドメイン名(またはCloudFrontのドメイン)/posts/hazimemashite/
のパスで無事、サブディレクトリのページに遷移できました!
終わりに
Astroのドキュメントは各プラットフォームごとにデプロイ方法が丁寧に描かれており、初心者に優しいなと感じました。
また今回実際に作成したページがこちらになります!
(スタイルとかレスポンシブがイマイチな気がするので勉強して直したい、、、)
読んでいただいた方ありがとうございました!
参考