Next.js 애플리케이션에서 루트를 어떻게 정의하고 조직하는지에 대해 알아봅니다.
app
디렉토리 내에서, 폴더들은 루트를 정의하기 위해 사용됩니다.
각각의 폴더는 URL 세그먼트에 매칭되는 루트 세그먼트들을 나타냅니다. 중첩 루트를 생성하기 위해서는, 각각 폴더 안에 다른 폴더들을 중첩시킬 수 있습니다.
page.js
파일은 루트 세그먼트를 공개적으로 접근 가능하도록 만듭니다.
해당 예시에서, /dashboard/analytics
URL 경로는 상응하는 page.js
파일이 없기 때문에 공개적으로 접근 가능하지 않습니다. 해당 폴더는 컴포넌트나 스타일 시트, 이미지 등의 다른 파일들을 저장하는 데에 사용될 수 있겠지요.
알아두면 좋은 것 :
.js
,.jsx
, 또는.tsx
파일 확장자 모두 특별한 파일들(special files)을 만드는 데에 사용될 수 있습니다.
특별한 파일 규약(Special file conventions)는 각각의 루트 세그먼트를 위한 UI를 생성하는 데에 사용됩니다. 하나의 루트를 위한 고유한 UI를 보여주는 페이지들과, 복수의 루트들에서 공용으로 사용되는 레이아웃들이 가장 흔한 형태입니다.
예를 들어, 첫 페이지를 만들기 위해서는, app
디렉토리 내에 page.js
파일을 생성하고 리액트 컴포넌트를 익스포트하세요.
// app/page.js
export default function Page() {
return <h1>Hello, Next.js!</h1>
}
페이지와 레이아웃을 생성하는 것에 대해 더 알아보세요.
app
폴더 내의 위계는 URL 경로들에 직접적으로 매핑됩니다. 그러나, 루트 그룹을 생성하는 것을 통해 이러한 패턴을 무시할 수 있습니다. 루트 그룹은 아래와 같은 경우에 사용될 수 있습니다.
루트 그룹을 지정하려면 폴더 이름을 괄호로 감싸면 됩니다. (폴더 이름)
URL 구조에 영향을 주지 않으면서 루트를 만들기 위해서는, 연관된 루트들을 모아 그룹을 지정하면 됩니다. 괄호로 감싼 폴더들은 URL로부터 생략될 거에요. (예를 들어 아래의 (marketing)
이나 (shop)
같은 경우 말이죠.)
(marketing)
폴더나 (shop)
폴더 안의 루트들이 동일한 URL 위계를 갖고 있더라도, 각각의 폴더 안에 layout.js
를 추가함으로써, 그룹 별로 다른 레이아웃을 생성할 수 있게 됩니다.
하나의 레이아웃에 특정한 루트들을 도입하기 위해서는, 새로운 루트 그룹을 생성하고 (예를 들어 (shop)
) 같은 레이아웃을 공유하는 루트들을 해당 폴더 안으로 옮기세요 (예를 들어 account
와 cart
페이지들). 그룹 밖의 루트들은 레이아웃을 공유하지 않을 거에요 (예를 들어 checkout
페이지)
여러 개의 루트(root) 레이아웃을 생성하려는 경우, 가장 상위 폴더의 layout.js
를 제거하고, 각각의 루트(routes) 그룹에 layout.js
파일들을 추가하세요. 이는 완전히 다른 UI나 유저 경험을 제공하기 위해 애플리케이션을 각각의 파트로 분할하는 경우에 유용합니다. <html>
태그와 <body>
태그가 각각의 루트(root) 레이아웃에 추가되어야 합니다.
위의 예시에서, (marketing)
폴더와 (shop)
폴더는 각각의 고유한 루트(root) 레이아웃을 갖게 됩니다.
(marketing)/about/page.js
와 (shop)/about/page.js
는 /about
이라는 같은 경로를 리졸브하기 떄문에 에러를 발생시킬 겁니다.app/(shop)/layout.js
를 레이아웃으로 사용하는 /cart
페이지에서 app/(marketing)/layout.js
를 사용하는 /blog
페이지로 이동한다면, 전체 페이지가 로드되어야 합니다. 이 경우는 오직 복수의 루트 레이아웃을 가진 경우에만 해당합니다.만약 동적인 데이터들을 통해 루트들을 생성해야 하고, 그 전에는 정확한 세그먼트의 이름을 알 수 없다면, 빌드 타임에 프리렌더링 되거나 요청 시에 완성될 수 있는 동적 세그먼트를 이용할 수 있습니다.
동적 세그먼트는 대괄호로 폴더 이름을 감싸면 됩니다: [폴더 이름]
. 예를 들어, [id]
또는 [slug]
와 같이요.
동적 세그먼트는 레이아웃, 페이지, 루트, 그리고 generateMetadata
함수에 params
로 패싱됩니다.
예를 들어, 간단한 블로그의 경우 app/blog/[slug]/page.js
와 같은 루트를 포함할 수 있습니다. 이 경우 [slug]
가 블로그 포스트들을 나타내기 위한 동적 세그먼트가 됩니다.
// app/blog/[slug]/page.js
export default function Page({ params }) }
return <div>My Post</div>;
}
세그먼트를 위한 파라미터들을 생성하는 법을 알아보려면 generateStaticParams() 페이지를 참조하세요.
노트: 동적 세그먼트는
pages
디렉토리의 동적 루트와 동일합니다.
동적 세그먼트는 뒤따르는 세그먼트들을 모두 캐치할 수 있도록, 대괄호 안에 말줄임표를 추가함으로써 더 확장될 수 있습니다. [...폴더이름]
과 같이요.
예를 들어, app/shop/[...slug]/page.js
는 /shop/clothes
와 매치되고, /shop/clothes/top
이나 /shop/clothes/tops/t-shirts
에도 매치되는 식입니다.
대괄호 두 개로 파라미터를 감싸면, 캐치 올 세그먼트를 조건부로 사용할 수 있습니다.
예를 들어, app/shop/[[...slug]]/page.js
는 /shop
에 매치되고, /shop/clothes
, /shop/clothes/tops
, /shop/clothes/tops/t-shirts
에도 매치되는 식입니다.
캐치-올과 조건부 캐치-올의 차이는 파라미터 없이도 루트에 매치될 수 있다는 점입니다.
타입스크립트를 사용할 때는, 정의된 루트 세그먼트에 따라 params
타입을 추가할 수 있습니다.
// app/blog/[slug]/page.tsx
export default function Page({
params,
}: {
params: { slug: string };
}) {
return <h1>My Page</h1>;
}
노트 : 이는 추후 타입스크립트 플러그인을 통해 자동으로 될 수도 있습니다.