π‘οΈ Next.js App Router μλ¬ μ²λ¦¬ μμ κ°μ΄λ
π‘οΈ Next.js App Router μλ¬ μ²λ¦¬ μμ κ°μ΄λ
Next.js App Routerλ νμ΄μ§ λ¨μ, μ μ λ¨μμ λ€μν μλ¬ μ²λ¦¬λ₯Ό 곡μμ μΌλ‘ μ§μν©λλ€.
μμλ μ€λ₯(404 λ±)λΏλ§ μλλΌ μκΈ°μΉ λͺ»ν λ°νμ μ€λ₯κΉμ§ λ€λ£° μ μλλ‘ κ΅¬μ‘°νλ λ°©μμΌλ‘ μ 곡λ©λλ€. μ΄ κΈμμλ κ·Έ ν΅μ¬μΈ not-found.tsx, error.tsx, global-error.tsx νμΌμ μν κ³Ό μ¬μ©λ²μ μ€μ μμ μ ν¨κ» μ 리ν©λλ€.
β 1. not-found.tsx – 404 μλ¬ μ²λ¦¬
리μμ€λ₯Ό μ°Ύμ μ μλ μν©(μ: κ²μκΈμ΄ μ‘΄μ¬νμ§ μμ λ)μλ notFound() ν¨μλ₯Ό νΈμΆνμ¬ 404 νμ΄μ§λ‘ μ λν μ μμ΅λλ€.
μ¬μ© μμ
// app/posts/[id]/page.tsx
import { notFound } from 'next/navigation';
export default async function Page({ params }) {
const post = await getPostById(params.id);
if (!post) notFound();
return <div>{post.title}</div>;
}
컀μ€ν 404 νμ΄μ§ μμ±
// app/posts/[id]/not-found.tsx
export default function NotFound() {
return <h1>μ΄ κ²μκΈμ μ°Ύμ μ μμ΅λλ€.</h1>;
}
μ 체 μ±μ 곡ν΅μ μΌλ‘ μ μ©νκ³ μΆλ€λ©΄ app/not-found.tsxλ₯Ό μ¬μ©νλ©΄ λ©λλ€.
π₯ 2. error.tsx – νμ΄μ§ λ¨μ μμΈ μ²λ¦¬
μκΈ°μΉ λͺ»ν μλ¬(μ: fetch μ€ν¨, λ λλ§ μ€ μ€λ₯ λ±)λ ν΄λΉ λΌμ°νΈ ν΄λμ error.tsxλ₯Ό μΆκ°νμ¬ μ²λ¦¬ν©λλ€.
기본 ꡬ쑰
// app/dashboard/error.tsx
'use client';
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return (
<div>
<h2>μλ¬κ° λ°μνμ΅λλ€.</h2>
<p>{error.message}</p>
<button onClick={() => reset()}>λ€μ μλ</button>
</div>
);
}
- error: λ°μν μλ¬ κ°μ²΄
- reset(): μλ¬ μνλ₯Ό μ΄κΈ°ννκ³ μ»΄ν¬λνΈλ₯Ό μ¬λ λλ§
λ°λμ 'use client'κ° μ μΈλμ΄μΌ ν©λλ€.
π 3. global-error.tsx – μ μ μλ¬ μ²λ¦¬
λ£¨νΈ λ μ΄μμμμ λ°μν μλ¬(μ΄κΈ° λ λλ§ μ€ μλ¬ λ±)λ global-error.tsxλ₯Ό ν΅ν΄ μ²λ¦¬ν μ μμ΅λλ€.
μ¬μ© μμ
// app/global-error.tsx
'use client';
export default function GlobalError({ error, reset }: { error: Error; reset: () => void }) {
return (
<html>
<body>
<h1>μ±μ μ€λ₯κ° λ°μνμ΅λλ€.</h1>
<p>{error.message}</p>
<button onClick={() => reset()}>νμΌλ‘</button>
</body>
</html>
);
}
- 루νΈμ μμ΄μΌ νλ©°, <html>κ³Ό <body> νκ·Έλ₯Ό ν¬ν¨ν΄μΌ ν©λλ€.
- νμ΄μ§ μ ν μ μλ 볡ꡬλμ§ μμΌλ―λ‘ μλ reset() νμ
π μλ¬ λ³΅κ΅¬ νλ¦
error.tsx λλ global-error.tsxμμ reset() ν¨μλ₯Ό νΈμΆνλ©΄ ν΄λΉ μ»΄ν¬λνΈλ λ€μ μμ²λλ©° μ΄κΈ° μνλ‘ λμκ°λλ€.
<button onClick={() => reset()}>λ€μ μλ</button>
- API μλ² μΌμμ λ€μ΄, DB μ°κ²° μ€ν¨ λ± μΌμμ μ€λ₯ 볡ꡬμ ν¨κ³Όμ
- μλ‘κ³ μΉ¨ μμ΄ μ¬μ©μμκ² λΉ λ₯Έ 리νΈλΌμ΄ κΈ°λ₯ μ 곡
π μ€μ ꡬ쑰 μμ
app/
βββ layout.tsx
βββ global-error.tsx ← μ μ μμΈ μ²λ¦¬
βββ not-found.tsx ← μ 체 404 μ²λ¦¬
βββ dashboard/
βββ page.tsx
βββ error.tsx ← dashboard μ μ© μμΈ μ²λ¦¬
βββ not-found.tsx ← dashboard μ μ© 404 μ²λ¦¬
β μμ½
νλͺ© μν μμΉ
notFound() | 404 μ λ ν¨μ | μλ² μ»΄ν¬λνΈ λ΄λΆ |
not-found.tsx | 404 νμ΄μ§ | ν΄λ λλ λ£¨νΈ |
error.tsx | λΌμ°νΈ λ¨μ μλ¬ κ²½κ³ | νμ΄μ§ ν΄λ λ΄ |
global-error.tsx | μ μ μλ¬ κ²½κ³ (λ μ΄μμ μμ€) | app/ λ£¨νΈ |
reset() | μλ¬ μν μ΄κΈ°ν λ° μ¬λ λλ§ | error μ»΄ν¬λνΈ λ΄λΆ |
Next.js, App Router, μλ¬ νΈλ€λ§, μλ¬ κ²½κ³, not-found.tsx, error.tsx, global-error.tsx, reset ν¨μ, μμΈ μ²λ¦¬, μ¬μ©μ κ²½ν, SEO μ΅μ ν 10κ°