1. **ルーティング**
1.1. ルーティングって?
1.1.1. プロジェクトの骨格となる部分
1.1.2. 遷移先のURLを決定する作業
1.1.2.1. 実例を見てみよう
1.1.3. ルーティング設計やプロジェクト構成が開発の肝でもある
1.2. 階層構造の基本
1.2.1. 🌳をイメージ
1.2.2. Tree(Root)
1.2.2.1. Sub Tree(Root)
1.2.2.1.1. Leaf
1.2.2.1.2. Sub Tree(Root)
1.2.2.2. Sub Tree(Root)
1.2.2.2.1. Leaf
1.2.2.3. Sub Tree(Root)
1.2.2.3.1. Leaf
1.2.3. https://ja.next-community-docs.dev/docs/app-router/building-your-application/routing/
1.2.4. 混乱する用語
1.2.4.1. Root
1.2.4.1.1. ツリー or サブツリーの根本のフォルダ
1.2.4.2. Root Segment
1.2.4.2.1. Segment =部分/断片
1.2.4.2.2. サブツリーの各フォルダ
1.3. App Routerのルーティング
1.3.1. /app配下にフォルダやファイルを配置していく
1.3.1.1. /app/page.tsx
1.3.1.1.1. https://xxx.com
1.3.1.2. /app/dashboard/page.tsx
1.3.1.2.1. https://xxx.com/dashboard
1.3.1.3. /app/dashboard/settings/page.tsx
1.3.1.3.1. ネストされたルート
1.3.1.3.2. https://xxx.com/dashboard/settings
1.3.1.4. /app/tags/[slug]/page.tsx
1.3.1.5. 実例を紹介
1.3.2. ファイル規約
1.3.2.1. 以下のファイル名は特殊な役割を持っている
1.3.2.2. page
1.3.2.2.1. ルーティングとして認識
1.3.2.3. layout
1.3.2.3.1. ページ共通レイアウト作成
1.3.2.4. loading
1.3.2.4.1. ストリーミングとローディングUI
1.3.2.5. not-found
1.3.2.5.1. 404ページの作成
1.3.2.6. error / global-error
1.3.2.6.1. エラー時のページ作成
1.3.2.7. route
1.3.2.7.1. APIルーティングとして認識
1.3.2.8. template
1.3.2.8.1. 共通レイアウト作成
1.3.2.8.2. layoutと違って遷移すると再レンダリングされる
1.3.2.8.3. アニメーション遷移の実装時などに利用される
1.3.2.9. default
1.3.2.9.1. Pararell Routesで使用
1.3.2.10. コンポーネント階層
1.3.2.10.1. これらのファイル群は自動的に同階層(Root Segment)のpage.tsxにレンダリングされる
1.3.2.10.2. 裏ではどのようにレンダリングされているのか?
1.3.2.10.3. https://ja.next-community-docs.dev/docs/app-router/building-your-application/routing/#%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88%E3%81%AE%E9%9A%8E%E5%B1%A4
1.3.3. コロケーション機能
1.3.3.1. 関連するものは近い位置に配置すること
1.3.3.2. page.tsxを宣言せずに利用
1.3.3.2.1. pageを使用しなければルーティングとして認識されない
1.3.3.2.2. /app/dashboard/header.tsx /app/dashboard/footer.tsx /app/dashboard/utils.ts
1.3.3.2.3. /app/api/db.ts
1.3.3.2.4. 近い位置で管理=保守・運用しやすい
1.3.3.2.5. 使うかどうかはチーム次第
1.3.3.2.6. https://ja.next-community-docs.dev/docs/app-router/building-your-application/routing/#%E3%82%B3%E3%83%AD%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3
1.3.4. プロジェクト整理機能
1.3.4.1. プライベートフォルダ
1.3.4.1.1. ルーティングから除外する機能
1.3.4.1.2. フォルダの前にアンダースコアをつける
1.3.4.1.3. /app/dashboard/_components/button.tsx /app/dashboard/_lib/page.tsx
1.3.4.1.4. メリットは?
1.3.4.2. ルートグループ
1.3.4.2.1. プロジェクトをグループ化できる
1.3.4.2.2. フォルダ名を()で括る
1.3.4.2.3. /app/(admin)/dashboard/page.tsx /app/(marketing)/about/page.tsx
1.3.4.2.4. メリットは?
1.3.4.3. /src
1.3.4.3.1. /app内にプロジェクト設定を入れたくない場合に有効
1.3.4.3.2. /appはルーティングだけに集中させる
1.3.4.3.3. 個人的に/srcは導入しています
1.4. ベストプラクティス
1.4.1. ルーティング設計のベストプラクティス
1.4.1.1. 3つの戦略
1.4.1.1.1. **/appの外側にプロジェクトファイルを配置**
1.4.1.1.2. **/appの内側のトップフォルダにプロジェクトファイルを配置**
1.4.1.1.3. **機能やRouteごとにプロジェクトファイルを配置する**
1.4.1.1.4. プロジェクトやチームによって変わる
1.4.2. プロジェクト配置設計のベストプラクティス
1.4.2.1. Atomic Design
1.4.2.1.1. Atomic
1.4.2.2. Bulletproof-React
1.4.2.2.1. 採用率高めかも
1.4.2.2.2. featuresディレクトリを配置
1.4.2.2.3. 実際に作ってみよう
1.4.2.2.4. https://zenn.dev/t_keshi/articles/bulletproof-react-2022
1.5. 応用と発展
1.5.1. Parallel Routes
1.5.2. Intercepting Routes
2. **コンポーネント**
2.1. コンポーネントって?
2.1.1. アプリを構成する部品のこと
2.1.2. 部品が集まってアプリが完成する
2.1.3. 部品が作られる「場所」がNext.jsでは重要
2.1.3.1. クライアント側? or サーバー側?
2.1.3.2. まずはクラサバ関係を図解で理解しよう
2.1.3.3. Reactだと全てクライアント側で作ってきた
2.2. ClientComponent
2.2.1. ファイル先頭に"use client"
2.2.2. 無闇に使わない
2.2.3. ユースケース
2.2.3.1. Hooksを利用する時
2.2.3.1.1. useState
2.2.3.1.2. useEffect
2.2.3.1.3. useRef etc...
2.2.3.2. イベントハンドラを利用する時
2.2.3.2.1. onClick
2.2.3.2.2. onChange etc...
2.2.3.3. ブラウザAPIを利用する時
2.2.3.3.1. localStorage / sessionStorage
2.2.3.3.2. window / doucument
2.2.3.4. クライアント操作が多いコンポーネント
2.2.3.4.1. フォームコンポーネント
2.2.3.4.2. 検索コンポーネント
2.2.3.4.3. タブ切り替え/ ハンバーガーメニュー開閉
2.3. ServerComponent
2.3.1. デフォルトでServerComponent
2.3.2. **こちらを積極的に利用する**
2.3.2.1. なぜ?
2.3.2.1.1. データフェッチが高速になる
2.3.2.1.2. サーバー側でレンダリング(SSR)されるので JSバンドルサイズが削減される
2.3.2.1.3. クライアントのスペックにほぼ依存しなくなる
2.3.2.1.4. SEOの向上
2.3.2.1.5. セキュリティの強化
2.4. 注意点
2.4.1. Client Boundary
2.4.1.1. 子コンポーネントは自動的に ClientComponentになる
2.4.1.2. 意図しないClientComponent化に注意
2.4.1.3. Compositionパターンで回避はできる
2.4.1.3.1. 参考文献参照
2.5. ベストプラクティス
2.5.1. **ServerComponentを積極的に利用**
2.5.2. **ClientComponentは控えめに**
3. **レンダリング**
3.1. レンダリングって?
3.1.1. HTML/CSS/JSを組み合わせてページとして見れる状態すること
3.1.1.1. ①HTMLの骨格を形成
3.1.1.2. ②CSSでスタイリング
3.1.1.3. ③JSでインタラクティブ化
3.1.1.4. https://zenn.dev/oreo2990/articles/280d39a45c203e
3.1.2. クライアント側 or サーバー側でレンダリングするかでパフォーマンスが変わる
3.1.2.1. パフォーマンスって何で図る?
3.1.2.1.1. どれだけ早くユーザーのデバイスにコンテンツを表示させるか
3.1.2.1.2. TTFB etc...
3.1.3. Next.jsでは基本サーバー側でレンダリングさせる
3.1.3.1. クライアント側に負荷をかけさせない
3.1.3.2. 事前にデータフェッチしておくため
3.1.4. https://guydumais.digital/blog/next-js-the-ultimate-cheat-sheet-to-page-rendering/
3.2. Static Rendering
3.2.1. SSG
3.2.1.1. 最速
3.2.1.2. fetch("https://...", **{cache: "force-cache"}**)
3.2.1.3. 静的ページで有効
3.2.1.3.1. ドキュメント
3.2.1.3.2. ヘルプページ
3.2.1.3.3. ポリシーページ
3.2.1.3.4. 更新の少ないブログメディア等
3.2.2. ISR
3.2.2.1. これも早い
3.2.2.2. データのキャッシュ更新時間を 指定可能
3.2.2.3. 静的と動的の中間ページで有効
3.2.2.3.1. ブログメディア
3.2.2.3.2. ニュースサイト
3.2.2.3.3. ECサイト etc...
3.2.2.4. fetch("https://...", **{cache: {next: {revalidate: 3600}}}**)
3.2.2.4.1. revalidate = 再検証 = キャッシュ更新
3.2.2.4.2. 古いキャッシュを削除する時間を指定する
3.3. Dyanamic Rendering
3.3.1. SSR
3.3.1.1. 程よく早い
3.3.1.1.1. 初期ロードはClientComponentよりも早い傾向
3.3.1.2. リクエスト毎に都度サーバーでレンダリング
3.3.1.3. fetch("https://...", **{cache: "no-store"}**)
3.3.1.3.1. no-store = ストアしない = キャッシュしない
3.3.1.3.2. 都度データソースにアクセスする
3.3.1.4. 注意点
3.3.1.4.1. キャッシュされません
3.3.1.4.2. 都度APIリクエストを投げるので負荷がかかる
3.3.1.4.3. headers() / cookies()で自動的にSSRになる
3.4. Suspence / Streaming
3.4.1. ストリーミングって?
3.4.1.1. 段階的にUIやデータを提供すること
3.4.1.2. SSRの時に利用する
3.4.1.2.1. Streaming SSR
3.4.1.3. 見えていない部分は即時フォールバックUIを表示する
3.4.1.3.1. UXや滞在時間の向上
3.4.1.3.2. <Suspence fallback={"Loading..."} />
3.5. Pertial Pre Rendering(PPR)
3.5.1. レンダリング方式の新時代へ突入か
3.5.2. v15で実験的に導入されている
3.5.3. Partial = 部分的 Pre Rendering = 部分レンダリング
3.5.3.1. https://zenn.dev/akfm/articles/nextjs-partial-pre-rendering#ppr%E3%81%A8%E3%81%AF
3.5.3.2. Static と Dyanamicの混在が可能
3.5.3.2.1. Suspence境界の外側がStaticRendering
3.5.3.2.2. Suspence境界の内側がDyanamicRendering
3.5.3.2.3. https://nextjs.org/blog/next-15-rc#incremental-adoption-of-partial-prerendering-experimental
3.5.4. ページ単位からUI単位でのレンダリング方式決定へ
3.5.4.1. SSG or SSR等の判別議論が過去のものになる?
3.5.4.2. 今の内にキャッチアップしておくと良いかも
3.6. ベストプラクティス
3.6.1. **実装箇所によってレンダリング方式を判断できたらOK**
3.6.1.1. ex. ヘルプページ ⇨ SSG ex. プロフィールページ⇨ISR / SSR ex. タイムライン⇨SSR/CSR
3.6.1.2. ただ、PPRの登場で考えるべき粒度が変わる可能性も
3.6.1.2.1. ページ単位⇨UI単位へ
3.6.1.3. デフォルトではStaticRenderingを推奨
3.6.1.3.1. 必要に応じてDyanamic Renderingを
3.6.2. キャッシュも同様
3.6.3. Next.jsユーザーであれば理解しておくべきトピック
4. **メタデータ**
4.1. メタデータって?
4.2. 静的メタデータ
4.3. 動的メタデータ
4.4. ベストプラクティス
5. **ミドルウェア**
5.1. ミドルウェアって?
5.1.1. URLリクエスト前に 実行される関数
5.1.1.1. お城の門番みたいなもの
5.1.1.2. 安全性を担保するために 実装される
5.1.1.3. ユースケース
5.1.1.3.1. ユーザー権限確認
5.2. マッチャーで指定可能
5.3. 注意点
5.3.1. 予期しない多数リクエストの発生
5.4. ベストプラクティス
6. **キャッシュ**
6.1. ちょっと難しいトピック
6.1.1. そもそもキャッシュって?
6.1.1.1. データを一時的に保存し 再度取り出しやすくすること
6.1.1.1.1. 例:図書館
6.1.1.1.2. 良く貸出される人気の本
6.1.1.1.3. 書物の奥底ではなく、フロント近くの本棚に置いておく
6.1.1.1.4. すぐに本が提供できて便利!
6.1.2. Request Memoization
6.1.2.1. 同じリクエストは「重複排除」される
6.1.2.1.1. https://nextjs.org/docs/app/building-your-application/caching#request-memoization
6.1.2.1.2. 注意点
6.1.2.2. ServerComponentでfetch()を使う場合のみ適用
6.1.2.2.1. ORM等で作った関数はメモ化されない
6.1.2.2.2. RouteHandler(API)内での利用では適用されない
6.1.2.2.3. fetch以外ならReact cacheを利用
6.1.2.3. コンポーネント最下層でfetchしても問題ない
6.1.2.4. 動的メタデータ設定の際等に効果を発揮する
6.1.2.4.1. generateMetadata()
6.1.2.4.2. 同じfetchリクエストしても重複排除される
6.1.2.5. キャッシュ期間
6.1.2.5.1. 永続的ではない
6.1.2.5.2. fetchリクエスト毎
6.1.3. Data Cache
6.1.3.1. アプリ全体に関わるキャッシュ
6.1.3.1.1. 理解しておかないと意図しないデータが返ってくる
6.1.3.2. fetch()でData Cache設定できる
6.1.3.2.1. fetch("https://...", **{cache: "force-cahce"})**
6.1.3.2.2. fetch("https://...", **{cache: "no-store"})**
6.1.3.2.3. fetch("https://...", **{cache: {next: {revalidate: 3600}}}**)
6.1.3.2.4. SSG/SSR/ISRが関係する
6.1.3.3. https://nextjs.org/docs/app/building-your-application/caching#data-cache
6.1.3.4. キャッシュ期間
6.1.3.4.1. 永続的
6.1.3.4.2. サーバーを再起動 / 再ビルドしてもData Cacheは残る
6.1.3.4.3. 最新のデータを返したいなら
6.1.3.4.4. 再検証を設けることも可能
6.1.4. Full Route Cache
6.1.4.1. ページ全体のキャッシュ
6.1.4.1.1. 静的なHTMLやRSC Payloadをキャッシュする
6.1.4.1.2. fetch()個々のキャッシュではない
6.1.4.2. Static Renderingのみ適用される
6.1.4.2.1. SSG / ISR時のみ
6.1.4.2.2. SSRの場合はキャッシュされない
6.1.4.2.3. https://nextjs.org/docs/app/building-your-application/caching#2-nextjs-caching-on-the-server-full-route-cache
6.1.4.2.4. AppRouterはStaticRenderingを推奨
6.1.4.3. キャッシュ期間
6.1.4.3.1. 永続的
6.1.4.3.2. ユーザー間を超えてキャッシュを共有される
6.1.4.3.3. 指定時には慎重に
6.1.5. Router Cache
6.1.5.1. ナビゲーション用のキャッシュ
6.1.5.1.1. ページを訪問するとRSCペイロードが自動キャッシュされる
6.1.5.1.2. クライアント側でメモリ内にキャッシュされる
6.1.5.2. <Link />
6.1.5.2.1. 静的ページ
6.1.5.2.2. 動的ページ
6.1.5.3. キャッシュを無効にしたいときは...
6.1.5.3.1. ServerActionsで
6.1.5.3.2. router.refresh
6.1.5.4. キャッシュ期間
6.1.5.4.1. セッション中のみ = ブラウザのタブが閉じるまで
6.1.5.4.2. 静的ページ
6.1.5.4.3. 動的ページ
6.1.5.4.4. staleTimes
6.1.6. ベストプラクティス
6.1.6.1. **キャッシュの挙動をちゃんと理解しよう**
6.1.6.1.1. 予期しないキャッシュが発生しなければOK
6.1.6.1.2. キャッシュすべき箇所も把握できれば最高
6.1.6.1.3. ドキュメントから最新情報を知ると尚良い
6.1.6.2. キャッシュをもっと制御したい場合
6.1.6.2.1. Remix等を利用する
6.1.6.2.2. WebAPI標準に遵守している
6.1.6.2.3. キャッシュの詳細なカスタマイズが可能
7. 参考
8. **データフェッチ**
8.1. fetch()
8.1.1. fetch("https://dummy.com/user/1")
8.1.2. Next.jsでは拡張されている
8.1.2.1. デフォルトでSSR
8.1.2.1.1. v14以前ではSSGがデフォルトだった
8.1.2.1.2. v15以降ではSSRがデフォルト
8.1.2.2. オプトインでSSG/SSR/ISRに変更可能
8.1.2.3. キャッシュ設定が簡単
8.1.2.4. Request Memoization
8.1.2.5. レンダリングで後述
8.2. ORM等を利用した関数
8.2.1. prisma.post.findMany();
8.2.2. Route Handler(API)で書く必要ない
8.2.2.1. Route Handlerって?
8.2.2.1.1. app/api/posts/route.ts
8.2.2.1.2. Next.jsでAPIが作れる機能の事
8.2.2.2. 通信回数が増える
8.2.2.3. APIを配布する予定がある場合は良いかも?
8.2.2.3.1. それならRailsやLaravelを利用するかも
8.2.2.4. データ送信では使うかも?
8.2.2.4.1. ただServerActionsが登場した
8.2.2.4.2. これでも利用するケースは少ないかも
8.2.3. キャッシュ方法は後述
8.3. サードパーティライブラリ
8.3.1. ClientComponentの場合
8.3.1.1. useSWR()
8.3.1.2. Tanstack Query
8.3.1.3. useEffect ← 非推奨
8.3.1.4. 基本的には非推奨
8.3.1.4.1. 学習コスト
8.3.1.4.2. パブリックなネットワークへ公開
8.3.1.4.3. JSバンドルサイズの増加
8.4. 並行データフェッチング
8.4.1. 同期よりも並行を優先
8.4.1.1. 並行=パラレル
8.4.1.2. 具体例
8.4.1.2.1. 家事
8.4.1.2.2. 洗濯物を回しながら、皿洗い
8.4.1.2.3. 空いた時間は別の仕事をすると効率的
8.4.2. https://nextjs.org/docs/app/building-your-application/data-fetching/fetching#parallel-and-sequential-data-fetching
8.4.3. コンポーネントに分割すると 自動的に非同期データフェッチになる
8.4.4. Promise.all()
8.4.4.1. const [results, tags] = await Promise.all([ getSearchResults(query), getRelatedTags(query) ]);
8.5. ベストプラクティス
8.5.1. **ServerComponentを利用する**
8.5.1.1. なぜ?
8.5.1.1.1. 初回ページ読み込み速度の向上
8.5.1.1.2. SEO向上
8.5.1.1.3. セキュア
8.5.1.1.4. キャッシュの利用
8.5.1.1.5. ただし、デメリットも
8.5.2. Container / Presentationパターンの意識
8.5.2.1. 最近知りました
8.5.2.2. https://zenn.dev/akfm/books/nextjs-basic-principle/viewer/part_2_container_presentational_pattern
8.5.2.3. Container = データ取得層
8.5.2.4. Presentation = 見た目の部分
8.5.2.5. 実装例
8.5.2.5.1. https://zenn.dev/akfm/books/nextjs-basic-principle/viewer/part_2_container_presentational_pattern
8.5.2.6. なぜ?
8.5.2.6.1. テストしやすくなる
8.5.2.6.2. Compositionパターンにも対応しやすい
8.5.2.7. 小規模ならオーバーエンジニアリングかも