Next.js는 파일 시스템 기반 라우팅(file-system based routing)을 사용합니다. 즉, 폴더와 파일을 이용해 라우트를 정의할 수 있습니다. 이 페이지에서는 레이아웃과 페이지를 생성하고, 이들 간에 링크를 만드는 방법을 안내합니다.
페이지 생성하기 (Creating a page)
페이지(page)란 특정 라우트에서 렌더링되는 UI입니다. 페이지를 만들려면 app
디렉토리 내에 페이지 파일을 추가하고, React 컴포넌트를 기본(default)으로 export하면 됩니다. 예를 들어, 인덱스 페이지(/
)를 만들려면:
// app/page.tsx
export default function Page() {
return <h1>Hello Next.js!</h1>
}
레이아웃 생성하기 (Creating a layout)
레이아웃(layout)은 여러 페이지에서 공유되는 UI입니다. 네비게이션 시 레이아웃은 상태를 보존하고, 상호작용이 유지되며, 다시 렌더링되지 않습니다.
레이아웃은 레이아웃 파일에서 React 컴포넌트를 기본 export하여 정의할 수 있습니다. 이 컴포넌트는 children
prop을 받아야 하며, 이 prop은 페이지 또는 또 다른 레이아웃이 될 수 있습니다.
예를 들어, 인덱스 페이지를 자식으로 받는 레이아웃을 만들려면 app
디렉토리에 layout.tsx
파일을 추가하세요:
// app/layout.tsx
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
{/* 레이아웃 UI */}
{/* children이 페이지 또는 중첩 레이아웃으로 렌더링될 위치 */}
<main>{children}</main>
</body>
</html>
)
}
위 레이아웃은 app
디렉토리의 루트에 정의되어 있으므로 루트 레이아웃(root layout)이라고 부릅니다. 루트 레이아웃은 필수이며 반드시 html
과 body
태그를 포함해야 합니다.
중첩 라우트 생성하기 (Creating a nested route)
중첩 라우트(nested route)는 여러 URL 세그먼트로 구성된 라우트입니다. 예를 들어, /blog/[slug]
라우트는 다음과 같이 세 부분으로 구성됩니다:
/
(루트 세그먼트)blog
(세그먼트)[slug]
(리프 세그먼트)
Next.js에서는:
- 폴더는 URL 세그먼트에 매핑되는 라우트 세그먼트를 정의합니다.
- 파일(
page
,layout
등)은 해당 세그먼트에 표시될 UI를 생성합니다.
중첩 라우트를 만들려면 폴더를 중첩해서 생성하면 됩니다. 예를 들어, /blog
라우트를 추가하려면 app
디렉토리에 blog
폴더를 만들고, /blog
를 공개하려면 page.tsx
파일을 추가하세요:
// app/blog/page.tsx
import { getPosts } from '@/lib/posts'
import { Post } from '@/ui/post'
export default async function Page() {
const posts = await getPosts()
return (
<ul>
{posts.map((post) => (
<Post key={post.id} post={post} />
))}
</ul>
)
}
폴더를 계속 중첩하여 더 깊은 중첩 라우트를 만들 수 있습니다. 예를 들어, 특정 블로그 포스트 라우트를 만들려면 blog
폴더 내에 [slug]
폴더를 만들고, 그 안에 page.tsx
파일을 추가하세요:
// app/blog/[slug]/page.tsx
function generateStaticParams() {}
export default function Page() {
return <h1>Hello, Blog Post Page!</h1>
}
폴더 이름을 대괄호로 감싸면(예: [slug]
) 동적 라우트 세그먼트(dynamic route segment)가 생성되어 데이터로부터 여러 페이지를 만들 수 있습니다. (예: 블로그 포스트, 상품 페이지 등)
레이아웃 중첩하기 (Nesting layouts)
기본적으로 폴더 계층 구조의 레이아웃도 중첩되어, children
prop을 통해 자식 레이아웃을 감쌉니다. 특정 라우트 세그먼트(폴더) 내에 layout
파일을 추가하여 레이아웃을 중첩할 수 있습니다.
예를 들어, /blog
라우트에 대한 레이아웃을 만들려면 blog
폴더 내에 layout.tsx
파일을 추가하세요:
// app/blog/layout.tsx
export default function BlogLayout({
children,
}: {
children: React.ReactNode
}) {
return <section>{children}</section>
}
위 두 레이아웃을 결합하면, 루트 레이아웃(app/layout.js
)이 블로그 레이아웃(app/blog/layout.js
)을 감싸고, 이는 다시 블로그 페이지(app/blog/page.js
)와 블로그 포스트 페이지(app/blog/[slug]/page.js
)를 감쌉니다.
페이지 간 링크 만들기 (Linking between pages)
라우트 간 이동을 위해 <Link>
컴포넌트를 사용할 수 있습니다. <Link>
는 HTML <a>
태그를 확장하여 prefetching과 클라이언트 사이드 네비게이션을 제공합니다.
예를 들어, 블로그 포스트 목록을 생성하려면 next/link
에서 <Link>
를 import하고, href
prop을 전달하세요:
// app/ui/post.tsx
import Link from 'next/link'
export default async function Post({ post }) {
const posts = await getPosts()
return (
<ul>
{posts.map((post) => (
<li key={post.slug}>
<Link href={`/blog/${post.slug}`}>{post.title}</Link>
</li>
))}
</ul>
)
}
<Link>
는 Next.js 애플리케이션에서 라우트 간 이동을 위한 기본적이고 권장되는 방법입니다. 더 고급 네비게이션이 필요하다면 useRouter
훅을 사용할 수도 있습니다.
API Reference
이 페이지에서 언급된 기능에 대해 더 알고 싶다면 아래 API 레퍼런스를 참고하세요.
출처: https://nextjs.org/docs/app/getting-started/layouts-and-pages