Next.jsのnext exportで生成された動的ページをLaravelで表示する
Next.jsのnext export
コマンドは通常、getStaticProps
とgetStaticPaths
の返り値を設定し、静的ページ(例:slug.html
)を生成しますが、この際、返り値を空にして、クライアントサイドの値で内容が変化するような静的ページ(例:[slug].html
)を生成することもできます。
ただ、[slug].html
はファイル名の通り、https://example.com/[slug].html
にアクセスされた時にしか表示されません。つまり、https://example.com/hello-world
やhttps://example.com/laravel-nextjs
などのURLを入力しても404エラーが返ってきます。それらのhtmlファイルは存在しないからです。
私の場合は、LaravelとNext.jsをミックスしたプロジェクトの時にこの問題に悩まされました。Laravelのpublic
ディレクトリにnext export
で生成されたhtmlファイルが混在する構成です。
Laravelの場合、この問題を解消するには専用のRouteを登録します。以下はサンプルコードです。
Route::get('/posts/{slug}', function ($slug) {
return File::get(public_path().'/posts/[slug].html');
});
https://example.com/posts/〇〇
にアクセスした時に、publicフォルダ内のpostsフォルダ内の[slug].htmlを表示せよ、という内容です。
※ /posts/{slug}
やFile::get(public_path().'/posts/[slug].html')
の部分は任意の文字列になるので、構成によって変えてください。
これだけ?と思うかもしれませんが、[slug].htmlは、slug部分を?slug="〇〇"
のクエリとして認識するため、特別なことをしなくても上手く表示されます。
もし、引数を使って何かやりたいのであれば、以下のように事前に引数を判断して無駄なAPIリクエストを発生させないくらいでしょうか。
Route::get('{id}', function ($id) {
if (is_numeric($id) && $id > 0) {
return File::get(public_path().'/posts/[slug].html');
}
abort(404);
});
現行のNext.jsでは、ページにアクセスした時にサーバーサイドで動くgetServerSideProps
を、getStaticProps
とgetStaticPaths
とセットで使うことができない(エラーになる)ため、クライアントサイドで動作するSPAのようなページとSSGによる静的ページが混在するような構成の場合などに役立つと思います。
※ もちろん、可能であればnext build
時に値を与えて静的ページを生成するのがベターです。