Next.js 애플리케이션에서 경로를 정의하고 구성하는 방법
Next.js는 폴더를 사용하여 경로를 정의하는 파일 시스템 기반 라우터를 사용합니다.
각 폴더는 URL 세그먼트에 매핑되는 Route Segment를 나타냅니다. 중첩 라우팅을 사용하려면 폴더를 서로 중첩시키면 됩니다.
Route Segment는 공개적으로 접근할 수 있도록 하기 위해 특수 page.js
파일이 사용됩니다.
위 예제에서는 /dashboard/analytics
경로에는 page.js
파일이 없기 때문에 공개적으로 접근할 수 없습니다. 이 폴더는 컴포넌트, 스타일시트, 이미지 등 기타 함께 배치할 파일을 저장하는 데 사용할 수 있습니다.
각 Route Segment에 대한 UI를 생성하기 위해 특별한 파일 규칙이 사용됩니다. 가장 일반적인 것은 경로에 고유한 UI를 표시하는 page
와 여러 경로에서 공유하는 layout
입니다.
예를 들어, 첫 페이지를 만들려면 앱 디렉터리에서 paga.js
파일을 추가하고 React 컴포넌트를 내보내면 됩니다.
export default function Page() {
return <h1>Hello, Next.js!</h1>
}
Next.js 13의 앱 라우터에는 페이지, 공유 레이아웃 및 탬플릿을 쉽게 만들 수 있는 새로운 파일 규칙이 도입되었습니다. 이 페이지에서는 Next.js 애플리케이션에서 이러한 특수 파일을 사용하는 방법을 알아봅니다.
페이지는 경로의 고유한 UI입니다. page.js
파일에서 컴포넌트를 내보내 패이지를 정의할 수 있습니다. 중첩 폴더를 사용하여 경로를 정의하고 page.js
파일을 사용하여 해당 경로를 공개적으로 접근할 수 있게 합니다.
앱 디렉터리 내에 page.js
파일을 추가하여 첫 번째 페이지를 만듭니다.
// `app/page.tsx` is the UI for the `/` URL
export default function Page() {
return <h1>Hello, Home page!</h1>
}
// `app/dashboard/page.tsx` is the UI for the `/dashboard` URL
export default function Page() {
return <h1>Hello, Dashboard Page!</h1>
}
Good to know
- 페이지는 항상 경로 ( route )의 하위 트리의 리프입니다.
- 페이지에는
.js
,.jsx
,.tsx
파일 확장자를 사용할 수 있습니다.- route segment에 공개적으로 접근할 수 있게 하기 위해서는
page.js
파일이 필요합니다.- 페이지는 기본적으로 서버 컴포넌트지만 클라이언트 컴포넌트로 설정할 수 있습니다.
- 페이지는 데이터를 가져올 수 있습니다.
레이아웃은 여러 페이지 간에 공유되는 UI입니다. 탐색에서 레이아웃은 상태를 보존하고 상호작용 상태를 유지하며 다시 랜더링하지 않습니다. 레이아웃은 중첩 될 수도 있습니다.
레이아웃은 기본적으로 lagout.js
파일에서 React 컴포넌트를 내보내서 정의할 수 있습니다. 컴포넌트는 랜더링 중에 자식 레이아웃이 있는 경우 또는 자식 페이지가 있는 경우 children 프로퍼티로 받아들여야 합니다.
export default function DashboardLayout({
children, // will be a page or nested layout
}: {
children: React.ReactNode
}) {
return (
<section>
{/* Include shared UI here e.g. a header or sidebar */}
<nav></nav>
{children}
</section>
)
}
Good to know
- 가장 위에 있는 레이아웃을 루트 레이아웃이라고 합니다. 이 필수 레이아웃은 애플리케이션의 모든 페이지에서 공유됩니다. 루트 레이아웃에는 HTML 및 본문 태그가 포함되어야 합니다.
- 모든 Route Segment는 선택적으로 자체 레이아웃을 정의할 수 있습니다. 이러한 레이아웃은 해당 세그먼트의 모든 페이지에서 공유됩니다.
- Route의 레이아웃은 기본적으로 중첩됩니다. 각 부모 레이아웃은 React의
children
프로퍼티를 사용하여 그 아래의 자식 레이아웃을 감싸줍니다.- Route Group을 사용하여 공유 레이아웃 안팎에서 특정 Route Segment를 선택할 수 있습니다.
- 레이아웃은 기본적으로 서버 컴포넌트지만 클라이언트 컴포넌트로 선택할 수 있습니다.
- 레이아웃은 데이터를 불러올 수 있습니다.
- 상위 레이아웃과 하위 레이아웃 간에 데이터를 전달할 수 없습니다. 그러나 경로에서 동일한 데이터를 두 번 이상 가져올 수 있으며, React 성능에 영향을 주지 않고 요청을 자동으로 중복 제거합니다.
- 레이아웃은 현재 Route Segment에 접근할 수 없습니다. Route Segment에 접근하기 위해서는 클라이언트 컴포넌트에서
useSelectedLayoutSegment
혹은useSelectedLayoutSegments
을 사용할 수 있습니다.- 레이아웃은
.js
,,jsx
,.tsx
파일 확장자를 사용할 수 있습니다.layout.js
파일과 page.js 파일은 같은 폴더에 정의할 수 있습니다. 레이아웃이 페이지를 감싸게 됩니다.
루트 레이아웃은 앱 디렉터리의 최상위 레벨에 정의되며 모든 경로에 적용됩니다. 이 레이아웃을 사용하면 서버에서 반환된 초기 HTML을 수정할 수 있습니다.
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}
앱 디렉토리에 루트 레이아웃이 포함되어야 합니다.
Next.js가 자동으로 생성하지 않으므로 루트 레이아웃에 <html>
및 <body>
태그를 정의해야 합니다.
기본 제공 SEO 지원을 사용하여 <head>
HTML 요소를 관리할 수 있습니다.
Route Group을 사용하여 여러 루트 레이아웃을 만들 수 있습니다.
폴더 내에 정의된 레이아웃은 특정 Route Segments에 적용되며 해당 Segment가 활성화될 때 렌더링됩니다. 기본적으로 파일 계층 구조의 레이아웃은 중첩되어 있으므로 children 프로퍼티를 통해 하위 레이아웃을 감싸게 됩니다.
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return <section>{children}</section>
}
위의 두 레이아웃을 결합하면 루트 레이아웃이 app/dashboard/layout.js
을 감싸게 됩니다.
Route Group를 사용하여 공유 레이아웃 안팎에서 특정 Route Segment를 선택할 수 있습니다.
탬플릿은 각 하위 레이아웃 또는 페이지를 래핑한다는 점에서 레이아웃과 유사합니다. 경로 전체에서 지속되고 있는 상태를 유지하는 레이아웃과 달리 탬플릿은 해당 세그먼트로 이동 시, 각 하위 레이아웃에 대해 새 인스턴스를 생성합니다. 즉, 사용자가 탬플릿을 공유하는 경로 사이를 탐색할 때 컴포넌트의 샐 인스턴스가 마운트되고, DOM 요소가 다시 생성되며, 상태가 보존되지 않고 efftect
가 다시 동기화됩니다.
이러한 특정 동작이 필요한 경우는 레이아웃보다는 탬플릿이 더 적합할 수 있습니다.
CSS 또는 애니메이션 라이브러리를 사용하여 애니메이션을 시작 / 종료하는 경우
useEffect
및 useState
에 의존하는 기능
기본 프레임워크 동작을 변경. 예를 들면 레이아웃 내부의 서스펜스 경계는 레이아웃을 처음 로드할 때만 폴백을 표시하고 페이지를 전환할 때는 표시하지 않습니다. 탬플릿의 경우 각 로드시에 폴백이 표시됩니다.
탬플릿을 사용해야 하는 경우가 아니라면 레이아웃을 사용하는 것이 권장됩니다.
탬플릿은 아래와 같이 정의할 수 있습니다.
export default function Template({ children }: { children: React.ReactNode }) {
return <div>{children}</div>
}
앱 디렉토리에서는 기본 제공 SEO를 사용하여 제목 및 메타 등의 <head>
HTML 요소를 수정할 수 있습니다.
메타데이터는 메타데이터 객체를 내보내거나 layout.js
또는 page.js
파일에서 generateMetadata
함수를 사용하여 정의할 수 있습니다.
Good to know
루트 레이아웃에
<title>
및<meta>
같은<head>
태그를 수동으로 추가해서는 안됩니다.