Firebase HostingでNext.jsのDynamic Routing用の設定をする
概要
こんにちは。https://twitter.com/tsux_ssbu です。
この記事はNext.jsをなぜかFirebase Hostingにデプロイしようとしてて、Dynamic Routingがうまくできず時間を溶かしてしまったぼくと同じ状況の人向けにどのように解決したのかが主な内容です。
こまってたこと
Next.jsのDynamic Routingの部分がローカル環境(next dev)では正常に動作するのに、firebase deployをしたら404 not found ページが表示されていたことです。
原因
pages/post/[pid].tsx
を実装してる前提で書いてます。
そもそも表示してほしいhtmlファイルが/post/pid
のPathにはないので404が表示されていました(404 pageが表示されているので当然といえば当然ですが)。Firebase Hostingでは next build && next export
で生成された静的ファイル(何の設定もしなければoutディレクトリに出力される)がhostingの対象になります。next exportはNext.js アプリを静的な HTML にエクスポートします。詳しくは以下の公式ドキュメントに詳しく書いてます。(next buildは.nextディレクトリに出力されてます)
next export
ではhtmlファイルが出力されるので/post/pid/index.html
がなければ当然404になります。おそらく何の設定もしていなければoutディレクトリにpost/[pid].html
が出力されているはずで、これでは/post/pid/
にアクセスしてもファイルはありません。(pidの値は可変でもあるので)
ローカル環境では動いていたのに!というのはそもそも出力しているファイルが違い、yarn dev
ではNext.jsの機能であるDynamic Routingを当然なにも設定せず使えるわけです。
解決方法
next.config.jsのtrailingSlash, firebase.jsonのrewritesを設定して解決しました。
① trailingSlashの設定(next.config.js)
trailingSlashをtrueにすることでURL末尾に強制的にスラッシュが付与してくれるもので、/post/pid
へのリクエストが自動的にスラッシュが付与されたURLへリダイレクトになります。
設定することで出力されるファイルがpost/[pid].html
からpost/[pid]/index.html
になります。
② rewritesの設定(firebase.json)
rewritesを設定することの目的は、複数の URL に対して同じコンテンツを表示するためです。
出力されているhtmlファイルはpost/[pid]/index.html
のみなのでpost/1
, post/100
へのリクエストでもこちらのファイルを表示したいのでこの設定をする必要があります。
公式ドキュメントが以下のように書いてねっていってるのでそれに従います。
regex URL パターンに一致する URL パスを開こうとすると、ブラウザーには、代わりにdestination URL にあるファイルの内容が表示されます。
こんなかんじ(`・ω・´)
"rewrites": [
{
"destination": "/post/[pid]/index.html",
"regex": "^/post/([^/]+?)(?:/)?$",
}]
regexのこのパターンはyarn build
した際に生成された.next/routes-manifest.json
のdynamicRoutesの箇所をコピペするだけでよさそうです。以下のコードは実際に出力されたやつです。
"dynamicRoutes": [
{
"page": "/post/[id]",
"regex": "^/post/([^/]+?)(?:/)?$",
"routeKeys": { "id": "id" },
"namedRegex": "^/post/(?<id>[^/]+?)(?:/)?$"
}
],
これでデプロイしたらDynamic Routingが機能しました(^-^)
trailingSlashいらんかも
trailingSlashにしたくない場合は、rewritesだけでも問題ないかもです。
/post/[pid].html
を表示させるかpost/[pid]/index.html
を表示させるかの違いなだけな気がしてます。確認できてないので知らんけど程度でもあります。
まとめ
Vercelの船に乗りたい!!!
Discussion
こんにちは、
現在はNext.jsのDynamic Routingの表示問題に取り組んでいて、この記事を見つけ読みました。
実はSOFでポストをしましたが(https://stackoverflow.com/questions/77936270/nextjs-dynamic-links-firebase)、まだ解決できていません。
環境などのバージョンまたは記事に載ってなくて気をつけるべきところは特にあるでしょうか。