Nested routing
- Next.js는 폴더를 이용해서 nested routes를 생성한다.
- 각 폴더에 위치한
page.tsx
파일은 라우트를 생성한다. 예를 들면 /app/dashboard/page.tsx
파일은 /dashboard
경로를 생성한다.
page.js
파일을 제외한 파일들은 라우트가 생성되지 않기 때문에 관련된 컴포넌트 등의 파일을 해당 폴더 내에 함께 위치할 수 있다. (colocation)
페이지별 공통 레이아웃 생성하기
import SideNav from '@/app/ui/dashboard/sidenav';
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<div className="flex h-screen flex-col md:flex-row md:overflow-hidden">
<div className="w-full flex-none md:w-64">
<SideNav />
</div>
<div className="flex-grow p-6 md:overflow-y-auto md:p-12">{children}</div>
</div>
);
}
/dashboard
폴더 안에 layout.tsx
파일을 생성하면 /dashboard
라우트에 속한 모든 페이지에 동일한 레이아웃이 적용된다.
- 상단의 코드에서
Layout
컴포넌트가 props로 받는 children
에 /dashboard
폴더에 위치한 다른 페이지 컴포넌트가 들어가는 것이다.
- 또한
layout
을 이용하면 공통 레이아웃을 제외한 children
으로 받는 페이지 컴포넌트만 리렌더링 된다는 장점이 있다. (partial rendering)
Root layout
/app/layout.tsx
파일에 적용한 UI는 애플리케이션 내 모든 페이지에 적용된다.
- 또한 root layout 파일을 metadata를 적용할 때도 사용할 수 있다.
Link 컴포넌트로 navigating 최적화하기
import Link from 'next/link';
export default function NavLinks() {
const pathname = usePathname();
return (
<Link
key={link.name}
href={link.href}
className="flex h-[48px] grow items-center justify-center gap-2 rounded-md bg-gray-50 p-3 text-sm font-medium hover:bg-sky-100 hover:text-blue-600 md:flex-none md:justify-start md:p-2 md:px-3"
>
<LinkIcon className="w-6" />
<p className="hidden md:block">{link.name}</p>
</Link>
);
}
Link
컴포넌트를 이용해 페이지를 이동하면 client-side navigation을 적용할 수 있다.
- 여전히 일부분이 서버에서 렌더링되더라도, 전체 페이지 새로고침 없이 더욱 빠른 페이지 이동을 제공할 수 있다.
Link
컴포넌트는 code splitting 기능을 제공하기 때문에 특정 페이지에서 에러가 발생하더라도 나머지 애플리케이션은 여전히 정상적으로 작동할 수 있다.
- 브라우저의 viewport에
Link
컴포넌트가 포함된다면 Next.js는 자동적으로 해당 링크에 연결된 페이지의 코드를 미리 불러온다. 따라서 유저가 해당 링크를 클릭했을 때 링크에 연결된 페이지는 이미 백그라운드에서 로드되었기 때문에 빠른 페이지 전환이 이루어진다.
네비게이션 바에서 현재 페이지 알려주기
'use client';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import clsx from 'clsx';
export default function NavLinks() {
const pathname = usePathname();
return (
<Link
key={link.name}
href={link.href}
className={clsx(
'flex h-[48px] grow items-center justify-center gap-2 rounded-md bg-gray-50 p-3 text-sm font-medium hover:bg-sky-100 hover:text-blue-600 md:flex-none md:justify-start md:p-2 md:px-3',
{
'bg-sky-100 text-blue-600': pathname === link.href,
},
)}
>
);
}
useNavigation()
hook을 이용해서 현재 path를 얻을 수 있다. 다만 hook을 사용하기 위해 해당 컴포넌트를 클라이언트 컴포넌트로 변경해야 한다.
useNavigation()
으로 가져온 pathname
이 link.href
와 일치할 경우 해당 링크 컴포넌트에 파란색으로 하이라이팅 효과를 준다.