Next.js 13 내부의 App Router는 페이지
, 공유 레이아웃
및 템플릿
을 쉽게 생성하기 위한 새로운 파일 규칙을 도입했다. 이 페이지에서는 Next.js 애플리케이션에서 이러한 특별한 파일을 사용하는 방법을 안내한다.
Pages
페이지
는 경로에 고유한 UI이다. page.js
파일에서 컴포넌트를 내보내어 페이지를 정의할 수 있다.
중첩된 폴더를 사용하여 경로를 정의하고 페이지.js 파일을 사용하여 경로에 대해 공개적으로 액세스할 수 있도록 한다.
앱 디렉토리 내에 page.js
파일을 추가하여 첫 번째 페이지를 만들어 보자.
// app/page.tsx
// `app/page.tsx` is the UI for the `/` URL
export default function Page() {
return <h1>Hello, Home page!</h1>;
}
// app/dashboard/page.tsx
// `app/dashboard/page.tsx` is the UI for the `/dashboard` URL
export default function Page() {
return <h1>Hello, Dashboard Page!</h1>;
}
참고사항
페이지는 항상 라우트 서브트리의 말단이다.
.js
, .jsx
, 또는 .tsx
파일 확장명을 페이지에 사용할 수 있다.
라우트 세그먼트를 공개적으로 액세스할 수 있도록 하려면 page.js
파일이 필요하다.
페이지는 기본적으로 서버 컴포넌트이지만 클라이언트 컴포넌트로 설정할 수도 있다.
페이지는 데이터를 가져올 수 있다.
Layouts
레이아웃
은 여러 페이지 간에 공유되는 UI이다. 탐색 중에 레이아웃은 상태를 유지하고 상호작용하며 다시 렌더링되지 않는다. 레이아웃은 중첩될 수도 있다.
layout.js
파일에서 React 컴포넌트를 default
exporting하여 레이아웃을 정의할 수 있다. 컴포넌트는 렌더링 중에 자식 레이아웃(있는 경우) 또는 자식 페이지로 채워질 children
prop를 허용해야 한다.
// app/dashboard/layout.tsx
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>
);
}
[ 참고 사항 ]
최상위 레이아웃은 Root layout
이라고 하며, 이는 애플리케이션의 모든 페이지에서 공유된다. Root layout
에는 html 및 body 태그가 포함되어야 한다.
어떤 경로 세그먼트든지 자체 레이아웃을 선택적으로 정의할 수 있다. 이러한 레이아웃은 해당 세그먼트의 모든 페이지에서 공유된다.
라우트의 레이아웃은 기본적으로 중첩된다. 각 부모 레이아웃은 React children
prop을 사용하여 그 아래에 있는 자식 레이아웃을 감싼다.
공유된 레이아웃을 선택적으로 사용하려면 Route Groups
를 사용할 수 있다.
레이아웃은 기본적으로 서버 컴포넌트
이지만 클라이언트 컴포넌트로 설정할 수도 있다.
레이아웃은 데이터를 가져올 수 있다. Data Fetching
부모 레이아웃과 그 자식 간에 데이터를 전달할 수는 없다. 그러나 경로에서 동일한 데이터를 여러 번 가져올 수 있으며, React는 자동으로 요청을 제거
하여 성능에 영향을 미치지 않는다.
레이아웃은 현재 경로 세그먼트에 액세스할 수 없다. 경로 세그먼트에 액세스하려면 클라이언트 컴포넌트에서 useSelectedLayoutSegment
또는 useSelectedLayoutSegments
를 사용할 수 있다.
• .js
, .jsx
, or .tsx
확장자를 사용할 수 있다.
동일한 폴더에 layout.js
파일과 page.js
파일을 정의할 수 있다. 레이아웃은 페이지를 래핑한다.
루트 레이아웃은 app
디렉토리의 최상위 수준에서 정의되며 모든 경로에 적용된다.
이 레이아웃을 사용하면 서버에서 반환된 초기 HTML을 수정할 수 있다.
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
[ 참고 사항 ]
app
디렉토리는 Root layout
을 포함해야 한다.
루트 레이아웃은 <html>
및 <body>
태그를 정의해야 한다. Next.js에서 자동으로 생성하지 않기 때문이다.
빌트인 SEO 지원을 사용하여 <head>
HTML 요소를 관리할 수 있다. 예를 들어, <title>
요소를 사용할 수 있습니다.
root groups
를 사용하여 여러 루트 레이아웃을 만들 수 있다.
루트 레이아웃은 기본적으로 Server Component
이며, Client Component로 설정할 수 없다.
pages
디렉토리에서 마이그레이션하는 경우, 루트 레이아웃은 _app.js
및 _document.js
파일을 대체한다.
폴더 내에서 정의된 레이아웃 (예: app/dashboard/layout.js
)은 특정 경로 세그먼트 (예: acme.com/dashboard
)에 적용되고 해당 세그먼트가 활성화되면 렌더링된다.
파일 계층 구조에서 레이아웃은 기본적으로 중첩되어 있으며, children
prop을 통해 하위 레이아웃을 감싸게 된다.
// app/dashboard/layout.tsx
export default function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
return <section>{children}</section>;
}
위 예제에서 두 레이아웃을 결합하면 루트 레이아웃 (app/layout.js
)이 대시보드 레이아웃 (app/dashboard/layout.js
)을 감싸고, 대시보드 레이아웃은 app/dashboard/*
내부의 경로 세그먼트를 감싸게 된다.
👇 두 레이아웃은 아래와 같이 중첩된다.
공유 레이아웃에 특정 경로 세그먼트를 선택적으로 포함하거나 제외하려면 Route Groups
를 사용할 수 있다.
Templates
템플릿은 레이아웃과 유사하게 각 자식 레이아웃이나 페이지를 래핑한다.. 레이아웃은 라우트 간에 지속되고 상태를 유지하지만, 템플릿은 각각의 자식에 대해 새 인스턴스를 만든다. 따라서 라우트를 이동하는 경우, 템플릿을 공유하는 라우트 간에 이동하면 컴포넌트의 새 인스턴스가 마운트되고 DOM 요소가 다시 생성되며, 상태는 보존되지 않으며 효과가 다시 동기화된다.
아래와 같은 특정 동작이 필요한 경우 레이아웃 대신에 템플릿을 사용하는 것이 더 적합할 수 있다.
useEffect
(예: 페이지 조회 기록 기록) 혹은 useState
(예: 페이지별 피드백 폼)에 의존하는 기능특별한 이유가 없다면 레이아웃을 사용하는 것이 좋다.
템플릿은 template.js
파일에서 기본적으로 React 컴포넌트를 내보내어 정의할 수 있다. 이 컴포넌트는 중첩된 세그먼트인 children
prop을 수락해야 한다.
// app/template.tsx
export default function Template({ children }: { children: React.ReactNode }) {
return <div>{children}</div>;
}
// app/template.tsx
export default function Template({ children }) {
return <div>{children}</div>;
}
👇 레이아웃과 템플릿이 있는 라우트 세그먼트의 렌더링된 출력은 아래와 같다.
<Layout>
{/* Note that the template is given a unique key. */}
<Template key={routeParam}>{children}</Template>
</Layout>
Modifying
<head>
app
디렉토리에서 내장된 SEO 지원을 사용하여 제목 및 메타 데이터와 같은 <head>
HTML 요소를 수정할 수 있다.
메타 데이터는 layout.js
또는 page.js
파일에서 metadata
객체 또는 generateMetadata
함수를 exporting 하여 정의할 수 있다.
import { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Next.js',
};
export default function Page() {
return '...';
}
루트 레이아웃에 <title>
및 <meta>
와 같은 <head>
태그를 수동으로 추가해서는 안된다. 대신 Metadata API
를 사용하여 스트리밍 및 <head>
요소 중복 제거와 같은 고급 요구 사항을 자동으로 처리해야 한다.
[ 출처 ]
https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts