7839

雑草魂エンジニアブログ

【Next】Next.js のルーティング(React Router ではなかった。。。)

最近、Next.js をよく使っている私だが、先日の案件で SPA で S3 などを用いた静的ウェブサイトとしてホスティングしたいという話になった。よし!今回も Next.js でいくぞ!と意気込んだが、検討した結果、通常の React で React Router を使って実装することになった。

今回は、その経緯に関して、整理しておく。

今回のアプリケーションの概略

page 構成を Next.js のフォルダ構成で記載する。

pages
  |-- companies/
  |   |-- index.tsx
  |   |-- [companyId]/
  |       |-- index.tsx
  |       |-- groups/
  |           |-- [groupId].tsx
  |           |-- index.tsx
  |-- index.tsx
  |-- _app.tsx
  |-- _document.tsx

会社という組織に、各グループが存在し、それぞれのグループで API で取得したデータを表示するようなアプリケーションとなっている。基本的に、全てAPIで会社、グループの新規作成/更新/削除を行えるようにする。(API に関しては、他の既存のシステムで使われているモノを使う。)S3 などを用いた静的ウェブサイトとしてホスティングしたいということで、Next.js の SSR は使えず、SSG で実現できないかと検討した。ここで、問題になったのがルーティングである。Next.js のルーティングについて改めて調べてみた。

Next.js のルーティング

Next.jsには、ファイルシステムベースのルーターがデフォルトで存在する。ファイルが pages/ ディレクトリに追加されると、自動的にルートとして使用できるようになる。

nextjs.org

  • pages/blog/index.js → /blog
  • pages/blog/first-post.js → /blog/first-post
  • pages/blog/[slug].js → /blog/:slug

Next.js 9 以降は、Dynamic Routing も実装されている。 [param] でフォルダ名やファイル名を定義することで、自動的にルーティングしてくれる。Dynamic Routing に関して、next export で静的ファイルとして出力した場合、上記のアプリケーションの場合、以下のようになった。

  1. /index.html
  2. /companies/index.html
  3. /companies/[companyId].html
  4. /companies/[companyId]/groups.html
  5. /companies/[companyId]/groups/[groupId].html

1と2に関しては、問題なくホスティングできるが、問題は残りの3つである。これをデプロイしただけでは、きちんと画面が表示されず、/companies/1 でアクセスがきた場合には、 /companies/[companyId].html を表示するようなリライトの設定をしてあげる必要がある。(Firebase hosting の場合は、firebase.json、Netlifyの場合は、_redirects にリライト設定を記述することができる。)

今回のアプリケーションにおいては、以下の観点から Next.js ではなく、通常の React + React Router での実装をすることとした。

  • データの取得に関して、データの更新頻度が高く、クライアントサイドでのAPI取得が主なため、Static HTML Export をするメリットがほぼない。さらに、リライト設定も必要になるので今後の拡張も考えると面倒。
  • SEO対策が必要なサイトではない
  • Next.jsのビルドの最適化などのメリットは、(設定は少し面倒であるが)webpackでも実現可能。

(ルーティングが静的なパスのみであれば、Next.js でいきたかったが、今回は動的なパスもあるので、断念することにした。)

(余談) React Router

reactrouter.com

React Router はURLとUIコンポーネントを同期させるライブラリである。

通常、React で SPA を開発すると、描画されるコンポーネントは切り替わっても、URL が変化することはない。(URLとUIコンポーネントが紐付いていない状態である。)そこで、URLとUIコンポーネントを同期させるためのデファクトのライブラリがreact-routerである。

React Router を使ったフレームワークも現在、開発中のようだ。

remix.run

(余談) Nuxt.js

Nuxt.js は、SPA、SSR、SSG の全て実装できる。

ja.nuxtjs.org

Nuxt.js は pages ディレクトリ内の Vue ファイルの木構造に沿って、自動的に vue-router の設定を生成する。すなわち、Nuxt.js のルーティングは、 vue-router で行われている。

当初は、勝手な思い込みで、Next.js も React Router でルーティングされているものだと勝手に勘違いしていたw(←ここが大きな勘違いであった。)

まとめ

Next.js は React の SSRフレームワークと言われ、ファイルシステムでデフォルトでルーティングができる機能が備わっていることもやっと腑に落ちた。どのフレームワークを採用するかは、やはり適材適所で選択すべきであると思えた。

また、次回、今回作成した React + React Router のスターターキット的なモノも紹介できたらと思っている。

それでは、ステキな開発ライフを。