← プログラミングページの先頭へ

Next.js: React フルスタック フレームワーク

Next.js は、React に基づく Web フレームワークで、ルーティング、サーバー側レンダリング、静的生成、データ取得、キャッシュ、SEO、およびバックエンド機能を提供します。

通常の React SPA と比較して、Next.js の最も重要な新機能は次のとおりです。

  • ファイル システム ベースの App Router。
  • React Server Components。
  • SSR、SSG、ISR およびその他のレンダリング戦略。
  • サーバー側のデータ取得とキャッシュ。
  • Metadata、Sitemap、その他の SEO 機能。
  • Route HandlersとServer Actions。
  • 画像、フォント、プロダクションビルドの最適化。

1. 中心となる概念

モジュール重要な概念優先順位
RoutingApp Router、Layout、Dynamic Routes、Link学ばなければなりません
ComponentsServer Components、Client Components、use client学ばなければなりません
RenderingSSR、SSG、CSR、Hydration学ばなければなりません
DataServer Fetching、Caching、Revalidation学ばなければなりません
SEOMetadata、Open Graph、Sitemap学ばなければなりません
AssetsImage、Font、Static Assets重要な
UXSuspense、Streaming、Loading、Error重要な
BackendRoute Handlers、Server Actionsオンデマンド
ArchitectureISR、Cache Components、PPR上級者向け
DeploymentStatic Export、Node Server、Docker重要な

Next.jsとReact+Viteの違い

能力React + Vite SPANext.js
React UIサポートサポート
クライアントルーティング通常はReact Routerを使用しますApp Router内蔵
CSRサポートサポート
SSR追加のソリューションが必要内蔵
SSG追加のソリューションが必要内蔵
React Server Components通常のVite SPAのデフォルト機能には属しません内蔵
API Routes独立したバックエンドが必要Route Handlers
SEO Metadata自己管理Metadata API内蔵
画像の最適化サードパーティのツールまたは自己実装next/image
データキャッシュ通常はTanStack Queryなどで管理されています。サーバーキャッシュ + オプションのクライアントキャッシュ
本番展開通常は静的ファイル静的ファイルまたは Node.js Server

Next.js は React を置き換えるものではありませんが、React に基づいてルーティング、レンダリング、サーバー側の機能、および構築規則を追加します。

2. インストールとプロジェクトの構造

プロジェクトを作成します:

pnpm create next-app@latest my-site

よく使用されるコマンド:

# 開発サーバー
pnpm dev

# 実稼働ビルド
pnpm build

# 実稼働サーバーを開始する
pnpm start

典型的なプロジェクト構造:

my-site/
├── app/
│   ├── layout.tsx
│   ├── page.tsx
│   ├── globals.css
│   ├── loading.tsx
│   ├── error.tsx
│   ├── not-found.tsx
│   │
│   ├── about/
│   │   └── page.tsx
│   │
│   ├── blog/
│   │   ├── page.tsx
│   │   └── [slug]/
│   │       └── page.tsx
│   │
│   └── api/
│       └── health/
│           └── route.ts
│
├── components/
├── lib/
├── public/
├── next.config.ts
└── package.json

その中には:

  • app/: ファイル システム ベースのルーティング。
  • components/: 再利用可能なコンポーネント。
  • lib/: ツールの機能、データアクセスなど。
  • public/: 静的リソース。
  • next.config.ts: Next.js 構成。

3. App Router: ファイル システム ルーティング

Next.js ファイルとフォルダーを使用してルートを定義します。

たとえば:

app/
├── page.tsx
├── about/
│   └── page.tsx
└── blog/
    └── [slug]/
        └── page.tsx

以下に対応します:

/                 → app/page.tsx
/about            → app/about/page.tsx
/blog/react       → app/blog/[slug]/page.tsx
/blog/typescript  → app/blog/[slug]/page.tsx

特別なファイル

ファイル機能
page.tsxルーティングページの定義
layout.tsx共有レイアウトを定義する
template.tsxLayout と似ていますが、ナビゲート中にインスタンスを再作成できます
loading.tsxルート読み込み状況
error.tsx配線エラー境界
not-found.tsxNot Found UI
route.tsHTTP Route Handler
default.tsxParallel Routes のデフォルトは UI

Layout

// app/layout.tsx

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <header>My Website</header>
        <main>{children}</main>
        <footer>Copyright</footer>
      </body>
    </html>
  );
}

Layout はネストできます。

たとえば:

app/
├── layout.tsx
└── blog/
    ├── layout.tsx
    └── page.tsx

blog/layout.tsx は、Blog ルートとそのサブルートにのみ適用されます。

Layout を共有すると、通常、クライアントがナビゲートしている間マウント状態が維持され、不必要な再レンダリングや状態の損失が回避されます。

4. Dynamic Routes

動的ルートは角括弧を使用して定義されます。

app/blog/[slug]/page.tsx

訪問:

/blog/react-basics

以下に対応します:

type Props = {
  params: Promise<{
    slug: string;
  }>;
};

export default async function BlogPage({ params }: Props) {
  const { slug } = await params;

  return <h1>{slug}</h1>;
}

Next.js 15/16 では、App Router の params は Promise となり、非同期で読み取る必要があります。

Catch-all Routes

[...slug]

たとえば:

/docs/react/hooks

取得可能:

{
  slug: ["react", "hooks"];
}

Optional Catch-all Routes

[[...slug]]

0 個以上のパス フラグメントと一致します。

Next.js は next/link を提供します。

import Link from "next/link";

export default function Navbar() {
  return (
    <nav>
      <Link href="/">Home</Link>
      <Link href="/blog">Blog</Link>
      <Link href="/about">About</Link>
    </nav>
  );
}

主な機能:

  • クライアントのナビゲーション。
  • ルートのプリフェッチ。
  • 不必要なページ全体の更新を減らします。
  • App Router のクライアント ルート キャッシュと連携します。

useRouter

イベント ハンドラー内を移動する必要がある場合は、次のようにします。

"use client";

import { useRouter } from "next/navigation";

export function NavigationButton() {
  const router = useRouter();

  return <button onClick={() => router.push("/blog")}>Open Blog</button>;
}

一般的に使用される方法:

方法機能
router.push()履歴に移動して追加する
router.replace()履歴の移動と置換
router.back()前のページに戻る
router.refresh()現在のルートの新しいサーバー コンテンツをリクエストします
router.prefetch()プリフェッチルーティング

router.refresh() は、すべてのサーバー キャッシュをクリアすることを意味するものではありません。データがまだ有効なサーバー側キャッシュから取得されたものである場合は、更新後もキャッシュされたデータが表示される可能性があります。

6. Server Components

App Router、Page、Layout ではデフォルトで Server Component になります。

たとえば:

// app/blog/page.tsx

export default async function BlogPage() {
  const posts = await getPosts();

  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}

Server Componentの特徴:

  • サーバー環境で実行します。
  • サーバー側のデータベース、ファイル、またはプライベート API に直接アクセスできます。
  • async/awaitが使えます。
  • 独自のコンポーネント実装コードを Client Component JavaScript としてブラウザに送信しません。
  • useState、useEffect、および他のクライアント Hook を直接使用することはできません。
  • window、document、APIなどのブラウザには直接アクセスできません。

Server Componentの値

Browser Request
       ↓
Next.js Server
       ↓
Server Component
       ↓
Fetch Data
       ↓
Render RSC Payload / HTML
       ↓
Browser

これにより、ブラウザーが実行する必要がある JavaScript の数が減り、データのフェッチがサーバー リソースの近くで行われるようになります。

注: Server Component はデフォルトでサーバー上で実行されますが、これはリクエストごとに再実行する必要があるという意味ではありません。実際の動作は、事前レンダリングとキャッシュ戦略にも依存します。

7. Client Components

ブラウザとの対話が必要な場合に使用します。

"use client";

import { useState } from "react";

export function Counter() {
  const [count, setCount] = useState(0);

  return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}

Client Component は次の用途に適しています。

  • useState、useEffect。
  • ユーザーインタラクションイベント。
  • React Hook Form。
  • TanStack Query Hooks。
  • ブラウザAPI。
  • ブラウザ環境を必要とするサードパーティ製コンポーネント。

use clientの実際の意味

"use client" はクライアント モジュールの境界を宣言します。

マークされたモジュールとその静的インポート依存関係がクライアント モジュール グラフに入ります。

ただし、次のことに注意してください。

Client Component は、最初の画面がサーバーによってまったく生成されないという意味ではありません (HTML)。

Next.js は Client Component の最初の HTML を事前レンダリングでき、その後ブラウザーは JavaScript をロードして Hydration を実行します。

推奨されるコンポーネント構成

BlogPage (Server Component)
    │
    ├── ArticleContent (Server Component)
    │
    ├── TableOfContents (Client Component)
    │
    └── LikeButton (Client Component)

原則:

はデフォルトで Server Component を保持し、対話が必要な部分のみを Client Component に分割します。

便宜上、ページ全体またはルート Layout に "use client" をランダムに追加しないでください。

8. Server ComponentとClient Componentの組み合わせ

Server Component は Client Component をインポートしてレンダリングできます。

// app/blog/page.tsx
import LikeButton from "@/components/LikeButton";

export default async function BlogPage() {
  const post = await getPost();

  return (
    <article>
      <h1>{post.title}</h1>
      <p>{post.content}</p>

      <LikeButton postId={post.id} />
    </article>
  );
}

Client Component:

"use client";

import { useState } from "react";

export default function LikeButton({ postId }: { postId: number }) {
  const [liked, setLiked] = useState(false);

  return (
    <button onClick={() => setLiked(!liked)}>{liked ? "Liked" : "Like"}</button>
  );
}

Server Component が Props を Client Component に渡す場合、通常、データは React のシリアル化要件を満たす必要があります。

通常の機能は Server/Client の境界を越えて自由に転送することはできません。 Server Functionsは特殊な伝達機構を持っています。

9. SSR、SSG、CSR、ISR

これら 4 つの概念は、主にレンダリングとコンテンツ更新戦略について説明します。

モード意味該当するシナリオ
CSR主にブラウザでページコンテンツをレンダリングします。高度にインタラクティブなアプリケーション
SSRHTML は要求されたときにサーバー上で生成されますライブまたはパーソナライズされたコンテンツ
SSGHTML はビルド時に事前生成されますブログ、ドキュメント
ISRデプロイ後にポリシーに従って生成されたコンテンツを更新する定期的に更新されるページ

CSR

Browser
   ↓
Load HTML + JavaScript
   ↓
React Executes
   ↓
Fetch Data
   ↓
Render UI

代表的な用途:通常のReact SPA。

SSR

Browser
   ↓
Request Page
   ↓
Server Fetches Data
   ↓
Server Renders HTML
   ↓
Browser Receives HTML
   ↓
Hydration

リクエスト時にコンテンツを決定する必要があるページに適しています。

SSG

Build Time
    ↓
Generate HTML
    ↓
Deploy Static Files
    ↓
Browser

ブログ、ドキュメント、About ページなど、変化の少ないコンテンツに適しています。

ISR

Static Content
      ↓
Cache Lifetime / Revalidation
      ↓
Regenerate or Refresh
      ↓
Updated Content

ISR は、Web サイト全体をバックグラウンドで定期的に再構築するのではなく、Next.js キャッシュおよび再検証メカニズムを使用して、対応するコンテンツを更新します。

Next.js16では、Cache Componentsを使用するかどうかに応じて、対応する構成機種を選択する必要があります。

10. Hydration

Hydration は、React がブラウザ内のサーバーによって提供される HTML を引き継ぎ、対話機能を確立することを意味します。

Server Generated HTML
          ↓
Browser Displays HTML
          ↓
Download Client JS
          ↓
React Hydration
          ↓
Interactive UI

たとえば、サーバーには次の出力があります。

<button>Count: 0</button>

ブラウザが Hydration を完了すると、このボタンは React で定義された対話型動作を取得します。

Hydration Mismatch

サーバーによって生成された HTML がブラウザの最初のレンダリング結果と一致しない場合、Hydration エラーが発生することがあります。

よくある理由:

  • レンダリング ステージは window または localStorage を直接読み取ります。
  • サーバーとクライアントは異なる時間を出力します。
  • 固定されていないランダムな値を使用します。
  • 一貫性のない条件付きレンダリング。
  • HTML のネストが無効です。

原則は、サーバー側とクライアント側の最初のレンダリング結果の一貫性を確保することです。

11. Server-side Data Fetching

Server Component は非同期操作を直接実行できます。

export default async function BlogPage() {
  const response = await fetch("https://api.example.com/posts");

  if (!response.ok) {
    throw new Error("Failed to fetch posts");
  }

  const posts = await response.json();

  return <PostList posts={posts} />;
}

クライアントからデータを取得する場合の違い

Server Fetching:

Next.js Server
      ↓
External API / Database
      ↓
Server Component
      ↓
Rendered Result

Client Fetching:

Browser
    ↓
TanStack Query
    ↓
Axios / Fetch
    ↓
Backend API

Server Fetching に適しています:

  • 記事の内容。
  • SEO関連データ。
  • 最初の画面に表示する必要がある公開データ。
  • プライベート API 資格情報をブラウザーのデータ アクセスに公開したくありません。

Client Fetching に適しています:

  • 非常にインタラクティブなデータ。
  • 継続的に更新する必要があるデータ。
  • ユーザーアクション主導のクエリ。
  • ローカル キャッシュと楽観的な更新。

この 2 つは混合することができます。

12. Next.js キャッシュメカニズム

バージョンが異なれば構成モデルも異なるため、キャッシュは App Router のより複雑な部分です。

区別する必要があります:

キャッシュタイプ主な機能
Request Memoization同じ React サーバー側レンダリング内での重複排除
Server Data / Cache Components Cacheリクエスト間でサーバー側のデータまたはコンポーネントの結果を再利用する
Router Cacheブラウザキャッシュルーティング関連 RSC Payload
Browser HTTP CacheJS、CSS、写真、その他の静的リソースをキャッシュします。

Request Memoization

同じ Server Component レンダリングでは、同じ GET Fetch リクエストで結果を再利用できます。

const post1 = await fetch(url);
const post2 = await fetch(url);

同じリクエスト条件が満たされる場合、実際のリクエストの重複を回避できます。

ただし、これは HTTP リクエストにわたる永続的なキャッシュと同等ではありません。

デフォルトの fetch の動作

現代の Next.js App Router では:

const response = await fetch(url);

永続的なデータ キャッシュはデフォルトでは使用されません。

ページがリクエスト間でデータを再利用する必要がある場合は、適切なキャッシュ戦略を採用する必要があります。

以下では主にNext.js16のCache Componentsモデルを紹介します。

13. Cache Components

有効にする:

// next.config.ts

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  cacheComponents: true,
};

export default nextConfig;

cacheComponents は次の機能にアクセスできます。

  • "use cache"。
  • cacheLife()。
  • cacheTag()。
  • revalidateTag()。
  • updateTag()。
  • Suspenseと共同で部分プリレンダリング。

Cache Components は、すべてのコンテンツが自動的にキャッシュされることを意味するのではなく、開発者が再利用に適していることを明示的に宣言することを意味します。

use cache

import { cacheLife } from "next/cache";

export default async function BlogPage() {
  "use cache";

  cacheLife("hours");

  const posts = await getPosts();

  return <PostList posts={posts} />;
}

ここにキャッシュされるのは、特定の Fetch Response だけではなく、関数またはコンポーネントの結果です。

cacheLife

cacheLife("hours");

キャッシュのライフサイクルを宣言するために使用されます。

カスタム キャッシュ ポリシーも構成できます。

cacheTag

import { cacheTag } from "next/cache";

export async function getPosts() {
  "use cache";

  cacheTag("posts");

  return fetchPostsFromDatabase();
}

Tag を使用すると、複数の関連キャッシュを同じ識別子で再検証できます。

14. Revalidation: キャッシュの再検証

Next.js 16 Cache Components は、いくつかの重要なメソッドを提供します。

revalidateTag

import { revalidateTag } from "next/cache";

revalidateTag("posts", "max");

関連するキャッシュを期限切れとしてマークし、Stale-While-Revalidate パターンを使用して更新します。

つまり、バックグラウンド更新を実行する前に古いコンテンツを返すことができます。

短期間の古いデータを許容できるブログや製品カタログなどのコンテンツに適しています。

updateTag

import { updateTag } from "next/cache";

updateTag("posts");

関連するキャッシュをただちに無効にし、次の読み取りでは古いコンテンツを返し続けるのではなく、新しいデータを取得する必要があります。

updateTag()はServer Actionsとのみ使用できます。

revalidatePath

import { revalidatePath } from "next/cache";

revalidatePath("/blog");

ルーティング パスに従って関連するキャッシュを再検証します。

コントラスト

方法機能一般的な用途
cacheLifeキャッシュのライフサイクルを定義する定期的に更新する
cacheTagタグキャッシュキャッシュのグループ化
revalidateTagバックグラウンドで無効化および更新ブログ、コンテンツ一覧
updateTag即時無効ユーザー送信後の即時一貫性
revalidatePathパスによる再検証ページコンテンツの更新

ここでのキャッシュ無効化管理は、TanStack Query の queryClient.invalidateQueries() と同じキャッシュ システムに属さない Next.js サーバー上で行われます。

15. SuspenseとStreaming

Next.js は React Suspense とストリーミング レンダリングをサポートします。

Suspense

import { Suspense } from "react";

export default function Page() {
  return (
    <main>
      <h1>Dashboard</h1>

      <Suspense fallback={<p>Loading...</p>}>
        <Analytics />
      </Suspense>
    </main>
  );
}

非同期結果がロード境界に個別に配置されるのを待つことができます。

Streaming

Browser Request
       ↓
Server
       │
       ├── Send Static HTML
       │
       ├── Send Loading UI
       │
       └── Send Async Content Later

これにより、ページ全体を送信する前に、すべてのデータが取得されるのを待つ必要がなくなります。

loading.tsx

// app/blog/loading.tsx

export default function Loading() {
  return <p>Loading blog...</p>;
}

Next.js は、対応するルートの積載境界を確立します。

16. Error Handling

error.tsx

"use client";

export default function ErrorPage({
  error,
  reset,
}: {
  error: Error & { digest?: string };
  reset: () => void;
}) {
  return (
    <div>
      <p>Something went wrong.</p>
      <button onClick={reset}>Try again</button>
    </div>
  );
}

error.tsx はルーティング セグメント エラー境界であり、Client Component は必須です。

これは主に、対応するコンポーネント ツリー内の Error Boundary によって捕捉できるエラーを処理することを目的としており、すべての種類のサーバーまたはイベント処理エラーを捕捉することを目的としたものではありません。

not-found.tsx

export default function NotFound() {
  return <h1>Page not found</h1>;
}

協力:

import { notFound } from "next/navigation";

if (!post) {
  notFound();
}

Not Foundページを表示できます。

17. MetadataとSEO

Next.js は、ページの SEO メタ情報の生成を容易にする Metadata API を提供します。

静的 Metadata

import type { Metadata } from "next";

export const metadata: Metadata = {
  title: "My Blog",
  description: "Articles about programming and technology",
};

ダイナミックMetadata

import type { Metadata } from "next";

type Props = {
  params: Promise<{ slug: string }>;
};

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const { slug } = await params;

  const post = await getPost(slug);

  return {
    title: post.title,
    description: post.summary,
  };
}

動的なブログ投稿に適しています。

Open Graph

export const metadata: Metadata = {
  title: "My Blog",
  openGraph: {
    title: "My Blog",
    description: "Programming articles",
    type: "website",
    images: ["/og-image.png"],
  },
};

Sitemap

// app/sitemap.ts

import type { MetadataRoute } from "next";

export default function sitemap(): MetadataRoute.Sitemap {
  return [
    {
      url: "https://example.com",
      lastModified: new Date(),
    },
    {
      url: "https://example.com/blog",
      lastModified: new Date(),
    },
  ];
}

ファイル規則を使用して、robots.txt、Open Graph などの画像を生成することもできます。

注: SSR/SSG は、検索エンジンがコンテンツを直接取得するのに役立ちますが、Next.js を使用すると自動的に良好な SEO ランキングが取得されるわけではありません。

18. generateStaticParams

動的ルーティングでは、generateStaticParams() を使用して、ビルド段階で既知のページを事前生成できます。

// app/blog/[slug]/page.tsx

export async function generateStaticParams() {
  const posts = await getPosts();

  return posts.map((post) => ({
    slug: post.slug,
  }));
}

Markdown または MDX ブログの場合、ビルド時に記事 Slug を取得し、対応するページを生成できます。

Markdown Files
      ↓
generateStaticParams()
      ↓
Known Slugs
      ↓
Static Blog Pages

これは個人のブログに非常に便利です。

純粋な静的エクスポートが必要な場合は、すべての動的ルートが静的エクスポートの制限を満たしていることも確認する必要があります。

19. next/image

Next.js は、組み込みの Image コンポーネントを提供します。

import Image from "next/image";

export default function Profile() {
  return <Image src="/avatar.jpg" alt="Avatar" width={300} height={300} />;
}

主な機能:

  • レスポンシブな画像。
  • 画像サイズの最適化。
  • レイアウトのオフセットを減らします。
  • ネイティブLazy Loading。
  • 環境に応じて最適化された画像リソースを提供します。

リモート画像の場合、許可されるリモート ソースを next.config.ts で設定する必要があります。

注: デフォルトの動的イメージの最適化には、通常、イメージの最適化をサポートする実行環境が必要です。純粋に静的にエクスポートする場合は、カスタム Loader を使用するか、組み込みの最適化およびその他の互換性のあるメソッドをオフにする必要があります。

20. next/font

Next.js はフォントの読み込みと最適化をサポートしています。

たとえば:

import { Geist } from "next/font/google";

const geist = Geist({
  subsets: ["latin"],
});

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={geist.className}>{children}</body>
    </html>
  );
}

主な値:

  • フォントの読み込みを最適化します。
  • 不要なフォント ネットワーク リクエストを削減します。
  • フォント切り替えによるレイアウトのずれを軽減します。
  • フォント リソースのビルド時のセルフホスティングをサポートします。

21. Route Handlers

Next.js は、route.ts を使用して HTTP API を定義できます。

たとえば:

// app/api/health/route.ts

export async function GET() {
  return Response.json({
    status: "ok",
  });
}

以下に対応します:

GET /api/health

POST も使用できます。

export async function POST(request: Request) {
  const body = await request.json();

  return Response.json({
    received: body,
  });
}

Route Handlers は、一般的な HTTP メソッドをサポートします。

GET
POST
PUT
PATCH
DELETE
HEAD
OPTIONS

Django DRFとの関係

プロジェクトが既にバックエンドとして Django REST Framework を使用している場合:

Next.js Frontend
       ↓
Django DRF API
       ↓
PostgreSQL

API~Next.js Route Handlersのセットは必ずしも書き換える必要はありません。

Route Handlers は次の用途に使用できます。

  • 軽量のバックエンド インターフェイス。
  • Webhook。
  • サーバー側のプロキシまたは集約。
  • Next.js専用サーバー機能。

22. Server Actions / Server Functions

Server Actions では、クライアントとの対話によりサーバー機能をトリガーできます。

たとえば:

// app/actions.ts

"use server";

export async function createPost(formData: FormData) {
  const title = formData.get("title");

  // Validate input and check authorization
  // Save post to database
}

フォーム:

import { createPost } from "./actions";

export default function PostForm() {
  return (
    <form action={createPost}>
      <input name="title" />
      <button type="submit">Create</button>
    </form>
  );
}

実行プロセス:

Browser Form
      ↓
Server Action
      ↓
Validation / Authorization
      ↓
Database / Backend API
      ↓
Revalidation
      ↓
Updated UI

Server Actions は、フォーム送信やデータ変更などの処理に適しています。

次の点に注意する必要があります。

  • Server Actions は通常のフロントエンド関数ではありません。
  • クライアント呼び出しによりサーバー通信がトリガーされます。
  • サーバー側の検証と権限チェックを実行する必要があります。
  • 関数がサーバー ファイルに記述されている限り、関数は本質的に安全であると想定すべきではありません。
  • 従来のすべての HTTP API の代替品としては適していません。

Django + Orval + TanStack Query の完全な API アーキテクチャがすでにある場合は、Server Actions に強制的に移行する必要はありません。

23. proxy.ts

Next.js 16 では、古い Middleware ファイル命名規則が proxy.ts に置き換えられます。

たとえば:

// proxy.ts

import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

export function proxy(request: NextRequest) {
  return NextResponse.next();
}

次の用途に使用できます。

  • リダイレクトをリクエストします。
  • URL書き換え。
  • いくつかのアクセス制御プレロジック。
  • リクエスト情報に基づいてルーティングが行われます。

ただし、Proxy で多数の複雑なデータベース操作を実行することはお勧めできません。

さらに、Proxy のフロントエンド権限チェックは、バックエンド の実際の認証と認可を置き換えることはできません。

たとえば、ユーザーのプライベート データを含むインターフェイスでは、実際のサーバー側の処理ロジックでアクセス許可を検証する必要があります。

24. Turbopack

Turbopack は Next.js のビルド ツールです。

主な目標は次のとおりです。

  • 開発サーバーの起動を高速化します。
  • インクリメンタルコンパイルの効率を向上させます。
  • 大規模プロジェクトの更新フィードバック時間を短縮します。
  • Next.js の開発および実稼働ビルド プロセスをサポートします。

それとViteはどちらも建設ツール関連の技術ですが、サービスフレームワークの生態や実装方法が異なります。

React + Vite
    ↓
Vite Build Pipeline

Next.js
    ↓
Turbopack

Next.js 16 では、Turbopack が開発および運用ビルドのデフォルト ビルダーになりました。

特別なビルド構成を必要とする一部のプロジェクトでは、プラグインとビルドの互換性を確認する必要があります。

25. Static Export

Next.js は静的 Web サイトとして構築できます。

構成:

// next.config.ts

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  output: "export",
};

export default nextConfig;

実行:

pnpm build

通常、次のものが生成されます。

out/
├── index.html
├── about.html
├── blog/
└── _next/
    └── static/

その後、Nginx、オブジェクト ストレージ、または CDN に渡すことができます。

Static Exportの制限事項

純粋に静的なエクスポートは、リクエストを実行するサーバーに依存する次のような機能をサポートしません。

  • ダイナミックSSR。
  • Server Actions。
  • Route Handlers はサーバー処理が必要です。
  • リクエストに応じて Cookie/Header の動的ページを読み取ります。
  • Next.js サーバーに依存した動的な画像の最適化。
  • Proxy。

ただし、Server Components は、必ずしも Node.js サーバーを長時間実行する必要があることを意味するわけではありません。

必要なデータがビルド時に利用可能な場合、Server Components は引き続き静的プリレンダリングに参加できます。

26. Node.js ServerとDocker

SSR、Server Actions、動的データおよびその他の機能が必要な場合は、Node.js サーバーを展開できます。

開始:

pnpm build
pnpm start

Standalone 出力を構成することもできます。

// next.config.ts

const nextConfig = {
  output: "standalone",
};

export default nextConfig;

Standalone は、スタンドアロン サーバーの展開により適した出力を生成します。

典型的なアーキテクチャ:

Browser
    ↓
Nginx
    ↓
Next.js Node Server
    │
    ├── Server Components
    ├── Route Handlers
    ├── Server Actions
    └── Static Assets

Djangoを同時に使用する場合:

Browser
    ↓
Nginx
    │
    ├── /       → Next.js
    │
    └── /api/   → Django DRF

Docker展開

マルチステージ Dockerfile は次のように使用できます。

Stage 1: Install Dependencies
           ↓
Stage 2: Next.js Build
           ↓
Stage 3: Production Runtime

静的エクスポートを使用する場合、最終イメージには Nginx のみを含めることができます。

動的サーバー レンダリングを使用する場合は、Node.js ランタイム環境またはその他のサポートされている展開プラットフォームが必要です。

27. Next.jsとTanStack Query

Next.js と TanStack Query のサーバー側のデータ取得は相互に排他的ではありません。

Server Component

サーバーデータを直接取得するのに適しています。

export default async function Page() {
  const posts = await getPosts();

  return <PostList posts={posts} />;
}

Client Component

インタラクティブ性とクライアント側のキャッシュを必要とするコンテンツに適しています。

"use client";

function Profile() {
  const { data } = useUserProfileRetrieve();

  return <div>{data?.username}</div>;
}

選択原則

シーン優先順位を付ける
ブログ投稿のテキストServer Component
SEO コンテンツServer Fetching
より安定した公開データServer Cache
プロファイルの編集Client Component + RHF
複雑なフィルター検索TanStack Query
楽観的なアップデートTanStack Query
フォームの送信Server Actions または Mutation
リアルタイムのインタラクティブなデータClient Fetching / 購読する

Next.jsを採用したからといって、既存のTanStack Queryを削除する必要はありません。

ただし、TanStack Query を使用するためにすべての Server Components を Client Components に変更する必要はありません。

28. Next.js よくある質問

Q1: Next.js は React Router を完全に置き換えるものですか?

App Router を使用する Next.js プロジェクトの場合、通常、React Router は必要なくなります。

Next.js はすでにファイル システム ルーティングとクライアント ナビゲーションを提供しているためです。

Q2: Next.js ページのデフォルトはすべて SSR ですか?

いいえ。

ページは、事前レンダリング、動的レンダリング、部分的な事前レンダリング、またはクライアント側レンダリングを含む場合があります。

単純に Next.js = SSR と考えることはできません。

Q3: Server Component は Client Component よりも必ずしも高速ですか?

不確かな。

Server Component は通常、クライアント JavaScript を削減できますが、サーバーの計算とデータ取得の待ち時間が長くなる可能性もあります。

実際のパフォーマンスは、コンテンツ タイプ、キャッシュ戦略、ネットワーク状態、コンポーネント構造によって異なります。

Q4: Server ComponentはReact Hook Formと一緒に使用できますか?

クライアント Hook に依存する React Hook Form は、直接使用できません。

フォームは Client Component に配置する必要があります。

Q5: Next.js は純粋に静的な個人ブログに適していますか?

適切な。

以下のものと組み合わせることができます:

  • MDX。
  • App Router。
  • generateStaticParams。
  • Metadata。
  • Static Export。

ただし、Web サイトが主に純粋な静的コンテンツである場合は、Astro や Hugo など、コンテンツ サイトに重点を置いたツールを検討することもできます。

Q6: Next.js には別のバックエンドが必要ですか?

いいえ。

Next.js は Route Handlers と Server Actions を提供します。

ただし、プロジェクトに Django DRF のような完全なバックエンドがすでにある場合、Next.js は同じビジネス バックエンドを繰り返し構築することなく、フロントエンド レンダリングと SEO に集中できます。

概要

Next.js の中心となる知識は 4 つのレベルに分類できます。

レベルコアコンセプト
基本的なルーティングApp Router、Layout、Dynamic Routes、Link
レンダリングモデルServer Component、Client Component、SSR、SSG、Hydration
データとキャッシュServer Fetching、use cache、cacheLife、Revalidation
エンジニアリング能力Metadata、Streaming、Route Handlers、Server Actions、Deployment

推奨される学習順序:

  1. App Router とファイル ルーティング。
  2. Server ComponentsとClient Components。
  3. SSR、SSG、CSR、Hydration。
  4. Server-side Data Fetching。
  5. MetadataとSEO。
  6. Suspense、Streaming、Error Handling。
  7. Cache ComponentsとRevalidation。
  8. Route Handlers、Server Actions。
  9. Static Export、Docker、および運用環境の展開。

コア アーキテクチャは次のように要約できます。

React Components
       ↓
Next.js App Router
       │
       ├── Server Components
       │       ├── Data Fetching
       │       ├── Server Cache
       │       └── HTML / RSC Payload
       │
       └── Client Components
               ├── React Hooks
               ├── User Interaction
               ├── React Hook Form
               └── TanStack Query
                        ↓
                 Backend API

Next.js の主な価値は、すべての React コードをサーバー上で実行できるようにすることではなく、開発者がデータ、対話、キャッシュ、SEO のニーズに基づいて適切なサーバー側とクライアント側のレンダリング方法を選択できるようにすることです。


参考資料