페이지와 레이아웃 — page.tsx·layout.tsx 작성하기
직접 만들며 사이트 골격을 잡는다. 중첩 레이아웃과 children 의 정확한 의미까지.
3편에서 App Router 의 특수 파일 7가지를 정리했다. 그중 일상 99% 를 차지하는 두 파일 — page.tsx 와 layout.tsx — 를 손으로 직접 만들며 사이트 골격을 잡아본다.
이 두 파일의 관계는 단순하다 — layout 이 page 를 감싼다. 그리고 layout 은 또 다른 layout 으로 감싸질 수 있다. 양파 구조. 이번 편에서 그 양파를 한 겹씩 까본다.
1. page.tsx — 그 URL 의 본문
가장 단순한 페이지부터. app/page.tsx 는 루트 / URL 의 본문이 된다.
규칙 3가지면 끝.
export default가 반드시 있어야 한다. 함수 이름은 자유.- 반환은 JSX (=React 컴포넌트). HTML 같지만 자바스크립트.
- 파일 위치(
app/page.tsx) 가 곧 URL(/) 이다.
새 페이지를 만들고 싶으면 폴더만 추가. app/about/page.tsx 만들면 /about 즉시 생긴다 — 라우터에 등록하는 코드 따위 없다.
page · layout · loading 같은 예약 이름만 라우팅에 사용한다. 그래서 같은 폴더에 Button.tsx·utils.ts 를 두어도 라우트가 생기지 않는다. 컴포넌트·유틸이 라우트 폴더 옆에 같이 있어도 안전한 이유.
2. layout.tsx — children 을 감싸는 옷
레이아웃의 핵심은 {children}. 자식 페이지가 들어올 자리.
이 layout 이 한 번 적용되면 — /, /about, /blog/hello 어디로 가도 같은 헤더와 푸터가 그대로 보인다. 헤더만 적어두면 100개 페이지가 자동 공유.
주의 — 루트 layout 은 반드시 <html> 과 <body> 태그를 포함해야 한다. 다른 layout 은 그냥 <div> 로 감싸도 된다. 루트만 특별.
3. 중첩 레이아웃 — 폴더 단위로 layout 적용
이 게 진짜 강력한 부분. app/blog/layout.tsx 를 만들면 /blog/* 페이지들만 그 layout 으로 감싼다.
이제 /blog/hello 를 열면 — 루트 layout (헤더·푸터) → 블로그 layout (사이드바) → page (글 본문) 의 3겹 양파. /about 은 블로그 layout 을 거치지 않으니 사이드바 없음.
| URL | 거치는 레이아웃 | 결과 |
|---|---|---|
/ | root | 헤더 + 홈 + 푸터 |
/about | root | 헤더 + 소개 + 푸터 |
/blog/hello | root → blog | 헤더 + 사이드바 + 글 + 푸터 |
중첩은 깊이 제한 없지만 보통 2~3 단계까지.
4. 메타데이터 — layout 또는 page 에서 export
SEO 의 핵심인 <title>·<meta> 를 어떻게 넣나? <head> 를 직접 만지지 않고 metadata 객체를 export 한다.
Next.js 가 빌드 타임에 이 객체를 읽어 <head> 에 자동 삽입한다. page.tsx 에서 export 하면 그 페이지만, layout.tsx 에서 export 하면 그 layout 의 모든 자식 페이지가 기본값을 상속한다. 페이지별 override 가능.
7편 (Metadata API) 에서 OG 이미지·구조화 데이터까지 깊이 다룬다. 이번 편은 "이렇게 넣는다" 정도만.
metadata 는 서버 컴포넌트에서만 export 가능. 'use client' 붙은 파일에서 export 하면 무시되거나 에러. 클라이언트 컴포넌트에서 title 을 바꾸려면 document.title 직접 수정 또는 generateMetadata 함수 사용.
5. 실행 흐름 — 요청이 들어오면 무슨 일이
사용자가 /blog/hello 를 누르면 서버에서 일어나는 일.
- 라우터가 폴더 매칭 →
app/blog/[slug]/page.tsx찾음. - 위로 올라가며 layout 수집 → blog → root.
- 안에서 바깥 순서로 트리 조립 → page → blog → root.
- 각 컴포넌트를 서버에서 실행, HTML 문자열로 직렬화.
- 브라우저는 HTML 즉시 그리고 인터랙티브 부분만 hydrate.
개발자는 page.tsx·layout.tsx 만 적으면 된다. 이 단순함이 App Router 의 정체.
요약 — 4편 좌표
여기까지 정리. page.tsx 는 그 URL 의 본문, layout.tsx 는 자식을 감싸는 옷. 둘 다 default export 가 핵심. 루트 layout 은 <html>·<body> 필수, 다른 layout 은 자유. 중첩으로 폴더 단위 공통 UI 가능 — /blog/* 만 사이드바 같은 식. SEO 메타데이터는 export const metadata 한 줄. 다음 편에서 폴더 이름 [slug] 로 동적 라우팅을 본다.
다음 편 예고 — 동적·중첩 라우팅
[slug]·(group)·[...all] 폴더 이름 트릭 완전 정리. 5편.