Next.jsのnext exportで生成された動的ページをLaravelで表示する

公開日:2022/9/9更新日:2022/9/9

Next.jsnext exportコマンドは通常、getStaticPropsgetStaticPathsの返り値を設定し、静的ページ(例:slug.html)を生成しますが、この際、返り値を空にして、クライアントサイドの値で内容が変化するような静的ページ(例:[slug].html)を生成することもできます。

ただ、[slug].htmlはファイル名の通り、https://example.com/[slug].htmlにアクセスされた時にしか表示されません。つまり、https://example.com/hello-worldhttps://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を、getStaticPropsgetStaticPathsとセットで使うことができない(エラーになる)ため、クライアントサイドで動作するSPAのようなページとSSGによる静的ページが混在するような構成の場合などに役立つと思います。

※ もちろん、可能であればnext build時に値を与えて静的ページを生成するのがベターです。