Next.js 入門|「ページを作る」から「アプリとして育てる」まで最短で理解するガイド

はじめに

React を触り始めたとき、「コンポーネントは書けるけど、アプリ全体としてどう組み立てればいいの?」という壁に当たりがちです。ルーティング、API 通信、SEO、ビルド、デプロイ——“画面が出る”だけでは済まない要素が一気に増えます。

Next.js は、その「アプリに必要な周辺機能」を最初から揃えたフレームワークです。React の開発体験を保ちつつ、ルーティングや最適化、サーバー側の処理まで自然につなげられるのが強みです。
ただし、最初の学習でつまずくポイントもあります。たとえば 「App Router と Pages Router の違い」「Server Component / Client Component」「データ取得はどこでやるのが正解?」 など、概念が多いからです。

この記事では、Next.js を「なんとなく使える」ではなく、なぜそう書くのかが腹落ちする入門を目指します。座学で地図を作ってから、ハンズオンで小さなアプリを完成させます。


座学

1) Next.js は何を解決するのか

Next.js の価値は、ざっくり言うとこの3つです。

  • ルーティングが仕組みとして組み込まれている(URL と画面が自然につながる)
  • 表示の最適化(SSR/SSG/ISR)が選べる(SEO・速度・更新頻度のバランスを取れる)
  • サーバー処理(API / Server Actions / ミドルウェア)が同居できる(フロントとバックを“近く”に置ける)

React 単体だと、ルータやビルド、データ取得の設計を自分で寄せ集めます。Next.js はそれらを「よくある形」で統合してくれるので、設計の迷子になりにくいです。


2) App Router の基本:app/ が入口

最近の Next.js は **App Router(app/ ディレクトリ)**が中心です。入門でもこちらから始めるのが今の主流です。

  • app/page.tsx/(トップ)
  • app/about/page.tsx/about
  • app/blog/[slug]/page.tsx/blog/xxx(動的ルート)

「フォルダ = ルート」page.tsx = そのページ、この規則が軸になります。


3) Server Component と Client Component(重要)

App Router では、コンポーネントが大きく2種類に分かれます。

  • Server Component(デフォルト)
    • サーバー側でレンダリングされる
    • DB 取得や秘密情報を扱いやすい
    • ただし useStateonClick などのブラウザ機能は使えない
  • Client Component(先頭に 'use client'
    • ブラウザ側で動く
    • クリック・状態管理・DOM 操作ができる
    • ただしバンドルが増えるので増やしすぎ注意

入門でのコツはシンプルで、
**「表示だけは Server、操作が必要な部品だけ Client」**にするのが基本です。


4) データ取得の考え方:どこで fetch する?

Next.js では「どこでデータを取るか」が設計の要になります。

  • Server Component で fetch
    • 速い / SEO に強い / 秘密を隠せる
    • 画面表示に必要なデータはまずここで検討
  • Client Component で fetch
    • ユーザー操作に応じて再取得したいとき(検索、フィルタなど)
    • 体験は良いが、初期表示の SEO とは相性が変わる

まずは 「ページ表示に必要なもの=Serverで」
「操作で変わるもの=Clientで」 と覚えると迷いにくいです。


ハンズオン

ここでは、**「記事一覧 → 詳細 → お気に入り」**の最小アプリを作りながら、Next.js の基本を一気に通します。外部APIは使わず、ローカルの疑似データで完結させます。

0) プロジェクト作成

npx create-next-app@latest nextjs-intro-handson
cd nextjs-intro-handson
npm run dev

ブラウザで http://localhost:3000 を開いて動作確認します。


1) ルーティング:ページを増やす

app/ 配下にページを作ります。

app/about/page.tsx

export default function AboutPage() {
  return (
    <main style={{ padding: 24 }}>
      <h1>About</h1>
      <p>これは Next.js 入門ハンズオンの About ページです。</p>
    </main>
  );
}

これで /about にアクセスできるようになります。
Next.js 入門の最初の成功体験は、「ルーティングが自然に生える」ことです。


2) 疑似データを用意する(サーバー側で読む前提)

app/_data/posts.ts

export type Post = { slug: string; title: string; body: string };

export const posts: Post[] = [
  { slug: "hello-next", title: "Hello Next.js", body: "Next.js の世界へようこそ。" },
  { slug: "routing-basics", title: "Routing Basics", body: "app/ ディレクトリでルーティングします。" },
  { slug: "server-client", title: "Server vs Client", body: "必要なところだけ 'use client' にします。" },
];

_data は慣例的に「ルートではない補助フォルダ」として扱いやすいです(URL にならない)。


3) 一覧ページを作る(Server Component で表示)

app/posts/page.tsx

import Link from "next/link";
import { posts } from "../_data/posts";

export default function PostsPage() {
  return (
    <main style={{ padding: 24 }}>
      <h1>Posts</h1>
      <ul>
        {posts.map((p) => (
          <li key={p.slug}>
            <Link href={`/posts/${p.slug}`}>{p.title}</Link>
          </li>
        ))}
      </ul>
    </main>
  );
}

これで /posts に一覧が出ます。
この時点ではクリックは Link に任せていて、自前の状態管理はゼロ。それでもアプリとして成立します。


4) 動的ルートで詳細ページ([slug]

app/posts/[slug]/page.tsx

import { posts } from "../../_data/posts";
import { notFound } from "next/navigation";

type Props = { params: { slug: string } };

export default function PostDetailPage({ params }: Props) {
  const post = posts.find((p) => p.slug === params.slug);
  if (!post) return notFound();

  return (
    <main style={{ padding: 24 }}>
      <h1>{post.title}</h1>
      <p>{post.body}</p>
    </main>
  );
}

notFound() が Next.js っぽいポイントで、存在しない slug の時に 404 として扱えます。


5) “操作が必要な部品だけ” Client Component 化する

ここから「お気に入り」ボタンを追加します。クリックが必要なので Client Component にします。

app/posts/[slug]/FavoriteButton.tsx

"use client";

import { useEffect, useState } from "react";

export default function FavoriteButton({ slug }: { slug: string }) {
  const key = `fav:${slug}`;
  const [fav, setFav] = useState(false);

  useEffect(() => {
    setFav(localStorage.getItem(key) === "1");
  }, [key]);

  const toggle = () => {
    const next = !fav;
    setFav(next);
    localStorage.setItem(key, next ? "1" : "0");
  };

  return (
    <button type="button" onClick={toggle} style={{ padding: "8px 12px" }}>
      {fav ? "★ お気に入り解除" : "☆ お気に入り"}
    </button>
  );
}

そして詳細ページに組み込みます。

app/posts/[slug]/page.tsx(追記)

import FavoriteButton from "./FavoriteButton";
<FavoriteButton slug={post.slug} />

ここが Next.js の気持ちいいところで、
ページ全体は Server(軽い)、**ボタンだけ Client(操作)**という分割が自然にできます。


6) レイアウトを共通化する(layout.tsx

ページごとの余白やヘッダーを揃えたいので、共通レイアウトを作ります。

app/layout.tsx

import Link from "next/link";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="ja">
      <body>
        <header style={{ padding: 16, borderBottom: "1px solid #ddd" }}>
          <nav style={{ display: "flex", gap: 12 }}>
            <Link href="/">Home</Link>
            <Link href="/about">About</Link>
            <Link href="/posts">Posts</Link>
          </nav>
        </header>
        <div style={{ padding: 24 }}>{children}</div>
      </body>
    </html>
  );
}

これで全ページにナビが付き、アプリっぽさが一段上がります。


まとめ

Next.js 入門で押さえるべき要点は、結局のところ次の3つに集約されます。

  • ルーティングは app/page.tsx の規則で覚える(フォルダが URL になる)
  • Server / Client の分担が設計の中心(操作が必要な部品だけ 'use client'
  • データ取得はまず Server で考える(初期表示が強く、SEO/速度も取りやすい)

ハンズオンでは、一覧→詳細→お気に入りという“それっぽいアプリ”を、過剰なライブラリなしで組み立てました。Next.js の学習は、最初に 「分割の感覚」 を掴むと一気に楽になります。
「全部 Client にする」でも動きますが、Next.js の良さは薄れます。まずは 必要最小限だけ Client を癖にすると、その後の拡張(認証・DB・キャッシュ)も自然に繋がります。


投稿日

カテゴリー:

投稿者:

タグ:

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です