CheatSheet
日本語 icon日本語English iconEnglish
チートシートとはカンニングペーパーのことです。それが転じて、本来覚えることをまとめておいたものです。
要点をすぐに参照できるようにまとめてみました。

Next.js

エンジニアのためのWebチートシート

Next.jsはVercelが開発したReactベースのフルスタックフレームワークです。 App Router、Server Components、データフェッチング、ルーティングなどの機能をチートシートにまとめました。

セットアップ

プロジェクト作成

  • create-next-appでプロジェクトを作成します。

    npx create-next-app@latest my-app
    cd my-app
    npm run dev

ディレクトリ構成(App Router)

  • App Routerの基本的なディレクトリ構成です。

    my-app/
    ├── app/
    │   ├── layout.tsx      # Root layout
    │   ├── page.tsx        # / (Home)
    │   ├── loading.tsx     # Loading UI
    │   ├── error.tsx       # Error UI
    │   ├── not-found.tsx   # 404
    │   ├── about/
    │   │   └── page.tsx    # /about
    │   └── blog/
    │       ├── page.tsx    # /blog
    │       └── [slug]/
    │           └── page.tsx # /blog/:slug
    ├── public/
    ├── next.config.ts
    └── package.json

ルーティング

ファイルベースルーティング

  • ファイルの配置がそのままURLになります。

    app/page.tsx           → /
    app/about/page.tsx     → /about
    app/blog/page.tsx      → /blog
    app/blog/[slug]/page.tsx → /blog/:slug

動的ルート

  • 角括弧でパラメータを受け取る動的ルートです。

    // app/blog/[slug]/page.tsx
    type Props = {
      params: Promise<{ slug: string }>
    }
    
    export default async function BlogPost({ params }: Props) {
      const { slug } = await params
      return <h1>Post: {slug}</h1>
    }
    
    // app/shop/[...categories]/page.tsx
    // → /shop/a/b/c  params.categories = ["a","b","c"]
    
    // app/shop/[[...slug]]/page.tsx
    // → Optional catch-all (/ もマッチ)

Link & ナビゲーション

  • Linkコンポーネントとプログラム的なナビゲーションです。

    import Link from 'next/link'
    import { useRouter } from 'next/navigation'
    
    // Link component
    <Link href="/about">About</Link>
    <Link href={`/blog/${slug}`}>Post</Link>
    <Link href="/dashboard" prefetch={false}>
      Dashboard
    </Link>
    
    // Programmatic navigation
    const router = useRouter()
    router.push('/about')
    router.replace('/login')
    router.back()
    router.refresh()

データ取得

Server Component

  • デフォルトでサーバーコンポーネントです。サーバー側でのみ実行されます。

    // Server Component (default)
    async function UserList() {
      const users = await fetch('https://api.example.com/users')
        .then(res => res.json())
    
      return (
        <ul>
          {users.map(user => (
            <li key={user.id}>{user.name}</li>
          ))}
        </ul>
      )
    }

Client Component

  • 'use client'を宣言するとクライアントコンポーネントになります。

    'use client'
    
    import { useState } from 'react'
    
    export default function Counter() {
      const [count, setCount] = useState(0)
    
      return (
        <button onClick={() => setCount(count + 1)}>
          Count: {count}
        </button>
      )
    }

Loading & Error

  • loading.tsxとerror.tsxで状態を自動的に処理します。

    // app/blog/loading.tsx
    export default function Loading() {
      return <div>Loading...</div>
    }
    
    // app/blog/error.tsx
    'use client'
    export default function Error({
      error, reset
    }: {
      error: Error
      reset: () => void
    }) {
      return (
        <div>
          <h2>Something went wrong!</h2>
          <button onClick={reset}>Try again</button>
        </div>
      )
    }

レンダリング

SSR / SSG

  • Server-Side Rendering と Static Site Generation です。

    // SSG (default) - ビルド時に生成
    async function Page() {
      const data = await fetch('https://api.example.com/data')
      return <div>{data}</div>
    }
    
    // SSR - リクエスト毎に生成
    async function Page() {
      const data = await fetch('https://api.example.com/data', {
        cache: 'no-store'
      })
      return <div>{data}</div>
    }
    
    // SSG with generateStaticParams
    export async function generateStaticParams() {
      const posts = await getPosts()
      return posts.map(post => ({ slug: post.slug }))
    }

ISR(増分静的再生成)

  • revalidateを指定して一定時間後にページを再生成します。

    // ISR - 60秒ごとに再検証
    async function Page() {
      const data = await fetch('https://api.example.com/data', {
        next: { revalidate: 60 }
      })
      return <div>{data}</div>
    }
    
    // Page-level revalidate
    export const revalidate = 60

API & Server Actions

Route Handler

  • route.tsファイルでAPIエンドポイントを作成します。

    // app/api/users/route.ts
    import { NextResponse } from 'next/server'
    
    export async function GET() {
      const users = await getUsers()
      return NextResponse.json(users)
    }
    
    export async function POST(request: Request) {
      const body = await request.json()
      const user = await createUser(body)
      return NextResponse.json(user, { status: 201 })
    }

Server Actions

  • 'use server'でサーバー側の関数を直接呼び出せます。

    // Server Action
    async function submitForm(formData: FormData) {
      'use server'
      const name = formData.get('name')
      await saveToDatabase({ name })
    }
    
    // Usage in component
    export default function Form() {
      return (
        <form action={submitForm}>
          <input name="name" />
          <button type="submit">Submit</button>
        </form>
      )
    }

組み込みコンポーネント

Image コンポーネント

  • 画像の最適化を自動で行うコンポーネントです。

    import Image from 'next/image'
    
    <Image
      src="/photo.jpg"
      alt="Photo"
      width={800}
      height={600}
      priority        // LCP画像に指定
    />
    
    // fill mode
    <div style={{ position: 'relative', width: '100%', height: 400 }}>
      <Image
        src="/bg.jpg"
        alt="Background"
        fill
        style={{ objectFit: 'cover' }}
      />
    </div>

Metadata API

  • SEOメタデータをエクスポートで設定します。

    // app/layout.tsx or page.tsx
    import type { Metadata } from 'next'
    
    export const metadata: Metadata = {
      title: 'My App',
      description: 'Description here',
      openGraph: {
        title: 'My App',
        description: 'OG Description',
        images: ['/og-image.png'],
      },
    }
    
    // Dynamic metadata
    export async function generateMetadata({ params }) {
      const post = await getPost(params.slug)
      return { title: post.title }
    }

最適化

Font 最適化

  • next/fontでフォントを最適化して読み込みます。

    import { Inter, Noto_Sans_JP } from 'next/font/google'
    
    const inter = Inter({ subsets: ['latin'] })
    const noto = Noto_Sans_JP({
      subsets: ['latin'],
      weight: ['400', '700'],
    })
    
    export default function Layout({ children }) {
      return (
        <html className={inter.className}>
          <body>{children}</body>
        </html>
      )
    }

ミドルウェア & 環境変数

ミドルウェア

  • リクエスト処理前にロジックを実行します。

    // middleware.ts (project root)
    import { NextResponse } from 'next/server'
    import type { NextRequest } from 'next/server'
    
    export function middleware(request: NextRequest) {
      // Redirect
      if (request.nextUrl.pathname === '/old') {
        return NextResponse.redirect(new URL('/new', request.url))
      }
    
      // Add header
      const response = NextResponse.next()
      response.headers.set('x-custom', 'value')
      return response
    }
    
    export const config = {
      matcher: ['/dashboard/:path*', '/api/:path*']
    }

環境変数

  • 環境変数の設定方法です。

    # .env.local
    DATABASE_URL=postgresql://...
    NEXT_PUBLIC_API_URL=https://api.example.com
    
    # Server only (no NEXT_PUBLIC_ prefix)
    # process.env.DATABASE_URL
    
    # Client accessible (NEXT_PUBLIC_ prefix)
    # process.env.NEXT_PUBLIC_API_URL

引用・参考リンク

Related Goods

  • Next.jsをゼロから学べます!
今やNext.jsはWeb開発のデファクトスタンダードとなりました。
    Next.jsをゼロから学べます! 今やNext.jsはWeb開発のデファクトスタンダードとなりました。
    詳細をみる
  • Reactにまだ自信のない方はまずはここから!
最終章ではNext.jsについても簡単に触れられており、橋渡しのされた一冊です。
    Reactにまだ自信のない方はまずはここから! 最終章ではNext.jsについても簡単に触れられており、橋渡しのされた一冊です。
    詳細をみる
  • 「今の時代に一つだけ言語を学ぶなら?」
私は自信を持ってTypeScriptと答えます。TypeScriptを体系的に学ぶのにおすすめの一冊です。
    「今の時代に一つだけ言語を学ぶなら?」 私は自信を持ってTypeScriptと答えます。TypeScriptを体系的に学ぶのにおすすめの一冊です。
    詳細をみる
  • ケーブルに取り付け可能なTypeCとLightningの変換アダプタです。
スタイリッシュなデザインで、Apple製品との相性抜群です。
    ケーブルに取り付け可能なTypeCとLightningの変換アダプタです。 スタイリッシュなデザインで、Apple製品との相性抜群です。
    詳細をみる
  • お気に入りのサウンドデバイスをすぐ取り出せる位置にディスプレイさせておくことができます。
    お気に入りのサウンドデバイスをすぐ取り出せる位置にディスプレイさせておくことができます。
    詳細をみる

WebTerm - Recommended tools

WebTermは、ブラウザでLinuxコマンド・Gitコマンドを安全に実行でき、チュートリアル式で学べるターミナルサンドボックスです。
AIコーディングツールの普及に伴い、CLIの基礎知識を身につける重要性は増しています。実際のターミナルを操作するのに抵抗がある方でも、WebTermはローカル環境を壊す心配がありません。「会員登録不要・無料」で利用でき、学習環境として最適です。

WebTerm Logo

WebTerm

Browser Terminal Sandbox for Learning CLI

開く

All Cheatsheets

エンジニア・プログラマー向けの便利なチートシートを多数まとめています(SP/Tablet/PC対応)
すべてのチートシートを見る