
Parallel routes는 같은 layout 내에 여러 페이지를 동시에 렌더링 할 수 있는 라우팅 기술이다.
하나의 페이지에 여러 API를 이용해서 렌더링이 오래 걸리는 경우 해당 페이지가 로드 되기까지 시간이 오래 걸린다. 이럴 때 사용할 수 있는 것이 Parallel Routes 이다.

위 이미지는 공식 사이트에 나와 있는 이미지인데 보다시피 각 컴포넌트가 각각 렌더링을 하여 로드가 완료되면 나타난다. 컴포넌트 각각에 로딩과 로딩에 실패하면 보여줄 에러 컴포넌트를 따로 등록할 수 있다.
https://nextjs.org/docs/app/building-your-application/routing/parallel-routes
하나의 layout에서 각각의 컴포넌트를 렌더링하기 때문에 코드를 관리하기 더 쉽다.
Next.js의 Parallel Routes(병렬 라우팅)는 Slot을 사용한다. Slot은 모듈식으로 구조를 작성하는 데 도움을 준다.
Slot을 정의하기 위해서는 폴더 이름을 @FolderName 형식으로 작성해주면 된다.
Slot은 layout file의 props로 전달된다.
병렬 라우팅을 사용하려면 먼저 폴더를 추가해야 한다. 예를 들어 /dashboard 페이지에서 병렬 라우팅을 사용하려면,
📦app
┣ 📂dashboard
┃ ┣ 📂@member
┃ ┃ ┣ 📜loading.tsx
┃ ┃ ┗ 📜page.tsx
┃ ┣ 📂@newPost
┃ ┃ ┣ 📜loading.tsx
┃ ┃ ┗ 📜page.tsx
┃ ┣ 📜layout.tsx
┃ ┗ 📜page.tsx
아래와 같이 폴더 구조를 작성하면 된다. 이렇게 작성하면 dashboard의 layout.tsx에서 props로 member와 newPost Slots을 가질 수 있다. props로 가지기 때문에 /dashboard/member나 /dashboard/newPost 와 같은 URL로 이동할 경우 없는 페이지로 나온다.
// app/dashboard/layout.tsx
export default function DashboardLayout({
children,
member,
newPost,
}: {
children: React.ReactNode;
member: React.ReactNode;
newPost: React.ReactNode;
}) {
return (
<div>
<div>{children}</div>
<div className="flex gap-8">
<div className="p-[100px] m-12 shadow-2xl border-2 items-center">
{member}
</div>
<div className="p-[100px] m-12 shadow-2xl border-2 items-center">
{newPost}
</div>
</div>
</div>
);
}
// app/dashboard/@member/page.tsx
export default function Member() {
return <div>Member</div>;
}
// app/dashboard/@newPost/page.tsx
import Link from "next/link";
export default function NewPost() {
return (
<div>
<p>NewPost</p>
<Link href="/dashboard/ranking">Rankings</Link>
</div>
);
}
이렇게 코드를 작성하고 @newPost 폴더 내부에 ranking 폴더를 생성해서 /dashboard/ranking 으로 이동할 URL을 등록했다.

하지만 /dashboard/ranking 에서 페이지 새로고침을 하면 page not found가 나온다. 그 이유는 어느 슬롯이 활성화 되어 있는지 알 수 없기 때문이다. 이를 해결하기 위해서는 default 파일을 생성해 주어야 한다.
그래서 다음과 같이 파일 구조를 수정했다.
📦app
┣ 📂dashboard
┃ ┣ 📂@member
┃ ┃ ┣ 📜default.tsx
┃ ┃ ┣ 📜loading.tsx
┃ ┃ ┗ 📜page.tsx
┃ ┣ 📂@newPost
┃ ┃ ┣ 📂ranking
┃ ┃ ┃ ┗ 📜page.tsx
┃ ┃ ┣ 📜default.tsx
┃ ┃ ┣ 📜loading.tsx
┃ ┃ ┗ 📜page.tsx
┃ ┣ 📜default.tsx
┃ ┣ 📜layout.tsx
┃ ┗ 📜page.tsx
// app/dashboard/default.tsx
export default function DefaultDashboardPage() {
return <main>Default DashBoard Page</main>;
}
// app/dashboard/@newPost/default.tsx
export default function DefaultNewPost() {
return <div>Default NewPost</div>;
}
// app/dashboard/@member/default.tsx
export default function DefaultMember() {
return <div>Default Member</div>;
}
코드를 실행하면 다음과 같이 나온다.
