React, Vue

Next.js 13+ App Router ✅ Layout, Page, Loading, Metadata

jonbeo 2025. 11. 19. 10:57
반응형

 

 

기존 pages/ 라우터와 달리, App Router는 디렉터리 구조 자체가 라우팅 규칙이 됩니다.
app/ 디렉토리 안의 폴더마다 페이지, 레이아웃, 로딩, 에러 처리, 메타데이터를 담당하는 파일이 존재하죠.


🧩 1. App Router 기본 구조

 
app/
 ├─ layout.tsx         # 공통 레이아웃
 ├─ page.tsx           # 루트 페이지
 ├─ loading.tsx        # 로딩 상태
 ├─ error.tsx          # 에러 페이지
 ├─ about/
 │   ├─ page.tsx       # /about
 │   ├─ layout.tsx     # about 전용 레이아웃
 │   ├─ loading.tsx    # about 로딩 UI
 │   └─ error.tsx      # about 에러 핸들링
 └─ posts/
     ├─ page.tsx       # /posts
     └─ [id]/
         └─ page.tsx   # /posts/:id

 

📌 app/ 폴더 내부 구조 = 곧 URL 구조


🧱 2. layout.tsx – 공통 레이아웃

레이아웃은 해당 디렉토리의 모든 하위 페이지에 공통 적용됩니다.

 
// app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="ko">
      <body>
        <header>Header 영역</header>
        <main>{children}</main>
        <footer>Footer 영역</footer>
      </body>
    </html>
  );
}

 

📌 children은 현재 라우트의 page.tsx 내용이 들어가는 자리


🪄 3. page.tsx – 실제 페이지 컴포넌트

 
// app/about/page.tsx
export default function AboutPage() {
  return <h1>회사 소개 페이지</h1>;
}

 

📌 각 폴더에 page.tsx가 있으면, 그 경로가 자동으로 라우팅됩니다.
예: /about/page.tsxhttps://domain.com/about


⏳ 4. loading.tsx – 로딩 상태 UI

React Suspense를 기반으로 한 서버 컴포넌트 로딩 UI

 
// app/posts/loading.tsx
export default function Loading() {
  return <p>게시글을 불러오는 중입니다...</p>;
}

 

📌 fetch()가 지연되면 자동으로 loading.tsx가 표시됨


💥 5. 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>
  );
}

 

📌 use client가 꼭 필요함 (클라이언트 측에서 동작)
📌 reset()을 호출하면 다시 시도


🪶 6. metadata – SEO 및 메타태그 설정

App Router에서는 페이지별로 metadata를 설정 가능

// app/about/page.tsx
export const metadata = {
  title: "회사 소개 | My Website",
  description: "우리 회사는 최고의 서비스를 제공합니다.",
};

 

📌 결과적으로 <head> 영역에 자동 반영됨

 
<title>회사 소개 | My Website</title>
<meta name="description" content="우리 회사는 최고의 서비스를 제공합니다.">

⚙️ 7. 중첩 레이아웃 (Nested Layout)

app/about/layout.tsx 파일을 추가하면,
/about 이하 경로에만 적용되는 하위 레이아웃 구현 가능

 
// app/about/layout.tsx
export default function AboutLayout({ children }: { children: React.ReactNode }) {
  return (
    <section>
      <h1>About 영역</h1>
      {children}
    </section>
  );
}

 

📌 app/layout.tsxapp/about/layout.tsx 순으로 중첩 적용됨


🔄 8. 서버 컴포넌트 + 클라이언트 컴포넌트

App Router는 기본적으로 서버 컴포넌트(Server Component) 구조입니다.
클라이언트 전용 로직을 쓰려면 상단에 "use client" 선언 필요

 
// app/components/Counter.tsx
"use client";

import { useState } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>클릭: {count}</button>;
}

📊 9. 폴더 기반 라우팅의 장점

기능 Pages Router App Router
라우팅 구조 파일 이름 기반 디렉토리 기반
레이아웃 직접 import 자동 중첩
데이터 패칭 getStaticProps/getServerSideProps fetch() 내장 지원
로딩/에러 핸들링 직접 처리 파일 기반 자동 처리
SEO 설정 next/head metadata 내장

🧠 10. 실무 팁

loading.tsxerror.tsx폴더 단위 관리
✅ 컴포넌트는 기본적으로 서버, 동적 UI는 "use client"로 분리
✅ 라우트 경로는 폴더 구조만 봐도 설계 파악 가능
✅ SSG, ISR은 fetch() 옵션(next.revalidate)으로 설정


📝 마무리 정리

  • layout.tsx → 공통 UI
  • page.tsx → 페이지 콘텐츠
  • loading.tsx → Suspense 기반 로딩
  • error.tsx → 에러 UI
  • metadata → SEO 최적화
  • 모든 구조가 폴더 기반으로 자동 라우팅

👉 “라우트 설계 = 디렉터리 구조 설계”
이제 Next.js에서 폴더 하나면 페이지 하나, 관리가 훨씬 직관적입니다 💪

반응형