Next.js App Router移行メモ
May 6, 2024
遅いけどApp Routerにざっくり移行した
概要メモ
まあ要するに React の大きな変更に追従するための新しいアーキテクチャっぽい。お作法がだいぶ変更され、より server-client を意識しないとだめになった。
- React の新しい機能である Server Components, Stream with Suspense や Server Actions を実現するために開発された新アーキテクチャ
- 生のリクエストオブジェクト(header, cookie)は server-only functions の中でアクセス可能
- Layouts (
layout.tsx
?)はレンダラではない。パフォーマンス向上の為にキャッシュしたりするもの - デフォルトではページは Server Components にあたる
- もっと複雑なページは Client Components で実現できる
- Parallel Routes を使うと同じ layout で複数のページをレンダーできる
ディレクトリ内ファイル配置ルール
以下の名称に適切な拡張子(.tsx
など)をつけたものが App Router 管理のファイル
layout
共通の UI、ページごとに再レンダリングされないpage
アクセス可能なページの UIroute
サーバーサイド API エンドポイントerror
エラー UInot-found
template
共通 UI だが、ページごとに再レンダリングされる(?)
コンポーネントの階層構造
階層構造を意識しておくとネストした Route を実装する際にイメージしやすくなる。
layout > template > error > loading > not-found > page
ネストされた場合、Not found 以下がまるっと入れ替わる。
Pages Router との違い
Pages Router と違って、app 配下にファイルを配置したとて、そのファイル名の path でページがレンダリングされるわけじゃない。あくまでルールに沿ったファイル名で配置した場合に Routing に利用されることになる。
Pages Router からの移行
大体このステップ。
_app.tsx
,_document.tsx
をlayout.tsx
へ移行- 各 page を
page.tsx
へ移行 - 適宜
"use client"
を記述
このブログでは next-remote-mdx
を使っていたので、markdown を parse する箇所の処理を結構書き換えないといけなかった。
あと "use client"
を間違えて "use strict"
って書いちゃうとハマる。
rehype-img-sizeでエラー
next-remote-mdx用の画像のカスタムコンポーネントを実装するために rehype-img-size
を利用しているが、localでは動くがvercel環境では画像のサイズを取得しようとする際にライブラリ内でエラーが起こるので、パラメーターを渡すときに対策が必要。
[Error: [next-mdx-remote] error compiling MDX:ENOENT: no such file or directory, open '/var/task/public/~~~~~~'
以下で解決。参考
// https://github.com/ksoichiro/rehype-img-size/issues/1#issuecomment-1675573003const rehypeImgSizeDir = `${process.cwd()}/public`;const MDXRemoteOption: SerializeOptions = {mdxOptions: {remarkPlugins: [remarkUnwrapImages],rehypePlugins: [[rehypeImgSize, { dir: rehypeImgSizeDir }]],},};
まとめ
og 画像をいちいち配置したくなかったので next/og
を使うためにわざわざアップデートしたので次回は og 画像の自動化。