LoginSignup
15
10

Next.jsで作ったnext exportしたアプリをNginxで静的配信するための設定

Last updated at Posted at 2022-08-03

TL;DR

  • next exportは他のウェブフレームワークと違い、単一のhtmlではなくpages単位でhtmlを書き出す
  • そのため、一般的なSPA向けのサーバー設定では、ブラウザの更新時に404が発生してしまう
  • これを回避するには、/というパスへのリクエスト時に/index.html/hogeなら/hoge.htmlを探しに行く設定がwebサーバーに必要。下記はNginxの設定例。
location / {
    root /hoge/fuga/html;
    index index.html;
    try_files $uri $uri.html $uri/ /404.html;
}

はじめに

これまでは一番経験があり安定して開発できる技術としてVue2を使ってきたのですが、EoLも見えてきてそろそろ乗り換え…ということで、Next.jsを使い始めました。このとき静的にアプリケーションを配信するためのコマンドnext exportが、これまで触ってきたSPA(たとえばVue)の挙動と違い、そのためwebサーバーの設定で少し困ったので、メモしておきます。

Vueのビルドと違うところ

Vueの場合index.htmlはひとつですが、next exportpagesに配置されているコンポーネントの数だけhtmlが作成されます。SSG用のコマンドなので事前に全ページのHTMLを作成しておく、という思想なのでしょう。

たとえば

pages
├── _app.tsx
├── sample.tsx
└── index.tsx

こんな構造だと、next exportの結果は

dist
├── 404.html
├── _next
├── sample.html
└── index.html

こんな感じになるはずです。

困ったこと

上記でも、ローカルで開発している限りは、特に困ることがありません。しかしこのビルド結果をVueだとかと同じ感覚でデプロイすると(=単なるwebサーバーでの配信+index.htmlへのフォールバック)、ページリロード時に404となったり、トップページが表示されたりと、期待した挙動になりません。

期待した挙動にならない理屈

  1. CSRで/sampleを表示しているとする
  2. 更新すると、webサーバーはsampleというファイルを探しに行く(が、存在しない)
  3. 存在しないのでindex.htmlにフォールバックする(が、ページが/sampleとしてレンダリングされない!

2まではVueのルーティングでも起こる問題ですが、3はNext.jsで発生する問題です。
Next.jsでは、/sampleを更新する際は/sample.htmlを見に行かせる設定が必要となります。

Nginxの設定

下記のように設定することで、/hogeというURLをリクエストして/hogeが存在しなければ、/hoge.htmlを探しに行かせることができます。また、/へのリクエストは/index.htmlに流す、という設定も必要です。下記が設定ファイルの例です(冒頭と同じ)。

location / {
    root /hoge/fuga/html;
    index index.html;
    try_files $uri $uri.html $uri/ /404.html;
}

終わりに

インターネッツを探しても、あんまり記事が見つからなかったのですが、next exportをNginxで運用…というのはあんまりやるべきじゃないのでしょうか?
それとももっと良い方法がある?webサーバー+CSRがもう流行っていない?CRAを使うべき?
知見のある方はコメント頂けるとうれしいです。。。

15
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
10