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. 中心となる概念
| モジュール | 重要な概念 | 優先順位 |
|---|---|---|
| Routing | App Router、Layout、Dynamic Routes、Link | 学ばなければなりません |
| Components | Server Components、Client Components、use client | 学ばなければなりません |
| Rendering | SSR、SSG、CSR、Hydration | 学ばなければなりません |
| Data | Server Fetching、Caching、Revalidation | 学ばなければなりません |
| SEO | Metadata、Open Graph、Sitemap | 学ばなければなりません |
| Assets | Image、Font、Static Assets | 重要な |
| UX | Suspense、Streaming、Loading、Error | 重要な |
| Backend | Route Handlers、Server Actions | オンデマンド |
| Architecture | ISR、Cache Components、PPR | 上級者向け |
| Deployment | Static Export、Node Server、Docker | 重要な |
Next.jsとReact+Viteの違い
| 能力 | React + Vite SPA | Next.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.tsx | Layout と似ていますが、ナビゲート中にインスタンスを再作成できます |
loading.tsx | ルート読み込み状況 |
error.tsx | 配線エラー境界 |
not-found.tsx | Not Found UI |
route.ts | HTTP Route Handler |
default.tsx | Parallel 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 個以上のパス フラグメントと一致します。
5. Link とクライアント ナビゲーション
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 | 主にブラウザでページコンテンツをレンダリングします。 | 高度にインタラクティブなアプリケーション |
| SSR | HTML は要求されたときにサーバー上で生成されます | ライブまたはパーソナライズされたコンテンツ |
| SSG | HTML はビルド時に事前生成されます | ブログ、ドキュメント |
| 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 Cache | JS、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 |
推奨される学習順序:
- App Router とファイル ルーティング。
- Server ComponentsとClient Components。
- SSR、SSG、CSR、Hydration。
- Server-side Data Fetching。
- MetadataとSEO。
- Suspense、Streaming、Error Handling。
- Cache ComponentsとRevalidation。
- Route Handlers、Server Actions。
- 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 のニーズに基づいて適切なサーバー側とクライアント側のレンダリング方法を選択できるようにすることです。