들어가기에 앞서
이 포스트는 패러럴 라우트와 언터셉팅 라우트의 자세한 개념 설명 보다는 두 라우트를 결합할 때 필요한 약간의 개념을
설명하며, 두 라우트를 결합할 때 겪었던 이슈에 대해서 설명합니다.
위 라우트의 자세한 설명은 공식 사이트를 참고하시기 바랍니다.
Parallel Routes
기본 개념
패러럴 라우트란 병렬 라우트로서 동일한 레이아웃에서 page.tsx와 더불어 다른 페이지를 동시에 렌더링 하거나 분기를 통해 렌더링 할 수 있도록 도와줍니다.
Slots
패러럴 라우트는 slots이라는 이름으로 생성됩니다. Slots은 네이밍 규칙이며 @folder
처럼 정의됩니다.
아래 예시에서 Slots은 @analytics
와 @team
입니다.
Slots는 부모의 레이아웃에 props로 전달되고, 위 예시에서는 app/layout.js에서 children과 함께 병렬로 렌더링 할 수 있습니다.
const Layout = ({
children,
team,
analytics,
}:{
children: React.ReactNode
analytics: React.ReactNode
team: React.ReactNode
})=>{
return (
<>
{children}
{team}
{analytics}
</>
)
}
export default Layout
‼️주의할 점
위 예시에서 app/page.tsx 의 css를 width:100%, height:100vh 처럼 전체영역을 차지하도록 구성하였을 때,
team과 analytics가 렌더링 되지 않는 이슈를 겪었습니다.
병렬 라우팅을 이용할 때, 각 page들을 css를 통해 구분을 지어야 할 것 같습니다.
Intercepting Routes
기본 개념
인터셉팅 라우트란 가로채기 라우트로서 현재 레이아웃에서 다른 레이아웃으로 이동하지 않고, 다른 부분의 라우트를
나타낼 수 있습니다.
이 때, 해당 URL을 통해 직접 접근 하거나, 새로고침을 하게 되면 인터셉팅 라우트에 있는 레이아웃이 표시되지 않고, 기존의 페이지로 이동해야 합니다. 즉, 인터셉팅 라우트가 발생하지 않습니다.
Convention
인터셉팅 라우트는 (..)
규칙을 이용해 기존 페이지를 매칭할 수 있습니다.
(.)
는 동일 레벨의 세그먼트를 매칭합니다.(..)
는 한 레벨 위의 세그먼트를 매칭합니다.(..)(..)
는 두 레벨 위의 세그먼트를 매칭합니다.(...)
는 루트 app 디렉토리의 세그먼트를 매칭합니다.
Parallel Routes & Intercepting Routes 를 이용해 modal 만들기
특징
위 두 라우트를 이용해 모달을 구축할 경우 아래와 같은 특징을 얻을 수 있습니다.
- 모달에 대한 URL이 생성되어서 모달 컨텐츠를 공유할 수 있습니다.
- 페이지를 새로고침해도 모달 컨텐츠를 유지할 수 있습니다.
- 브라우저 뒤로가기 시 모달을 닫을 수 있습니다.
- 반대로 앞으로 가기 시 모달을 열 수 있습니다.
위 방법으로 모달을 구축하는 케이스들은 SNS에서 많이 보이는 것 같습니다.
- X(트위터) - 로그인, 피드
- 인스타그램 - 피드
기본 모델
// src/app/page.tsx
import Link from "next/link";
const HomePage = async () => {
return (
<div>
<Link href={"/photo"}> 모달열기 </Link>
<h1> hello page</h1>
</div>
);
};
export default HomePage;
// src/app/@modal/(.)photo/page.tsx
import Modal from "./modal";
const ModalPhotoPage = async () => {
return <Modal />;
};
export default ModalPhotoPage;
// src/app/photo/page.tsx
const PhotoPage = () => {
return <h1>Hello Photo Page</h1>;
};
export default PhotoPage;
각 코드블럭 상단의 파일명과 함께 봐주시길 바랍니다.
app/page
에서 Link를 통해 photo
로 이동하게 되면 app/photo/page
가 아니라 app/@modal/(.)photo/page
이 병렬 라우팅
을 통해 현재 레이아웃에서 모달이 나타나도록 구축되었습니다.
에러 해결1
이 때, 위 구성 처럼 루트에서 진행하게 되면 병렬 라우트까지는 진행할 수 있지만 모달열기
를 누르게 되면 404
에러가 나올 수 있습니다.
이 버그는 nextjs 에서 새로나온 번들인 turbopack
을 실행시키면 해결 할 수 있었습니다.
package.json 에서 --turbo
를 통해 터보팩을 실행시킬 수 있습니다.
"scripts": {
"dev": "next dev --turbo", // turbopack 실행
"build": "next build",
"start": "next start",
"lint": "next lint"
},
에러해결2
turbopack 번들을 사용하기에 다른 라이브러리가 지원하지 않아서 사용 못하는 상황이 생길 수 있고,
현재 turbopack 번들은 next dev
에서만 사용 가능하기 때문에 다른 방법의 해결책도 찾아보았습니다.
라우트그룹을 이용해 모달을 묶어주면 해결할 수 있었습니다.
// src/app/layout.tsx
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body>
{children}
</body>
</html>
);
}
// src/app/(home)/layout.tsx
export default function GroupHomeLayout({
children,
modal,
}: Readonly<{
children: React.ReactNode;
modal: React.ReactNode;
}>) {
return (
<html>
<body>
{children}
{modal}
</body>
</html>
);
}
// src/app/(home)/page.tsx
import Link from "next/link";
const GropHomePage = async () => {
return (
<div>
<Link href={"/photo"}> 모달열기 </Link>
<h1>group hello page</h1>
</div>
);
};
export default GropHomePage;
app/layout.tsx에서 modal
을 불러오지 않고, (home) 아래의 layout.tsx와 page.tsx가 생기면서 (home) 에서 modal
을 호출하고, 이동한다면 정상 동작하는 것을 확인할 수 있었습니다.
버그가 발생하지 않았던 환경
위 모달이 루트에서 생성되는게 아니라 depth가 내려가게 되면 어떤 에러도 발생하지 않았습니다.
/foo 에서 /foo/bar로 Link를 통해 이동하게 되면 처음 의도했던 대로 동작하게 됩니다.
마지막으로
위 두 라우트를 결합해 모달을 만들어 활용한다는 것을 접한 후 흥미로워 nextjs14의 공식 문서를 보고 어떻게 동작하게 되는지
간단하게 테스트를 하려고 했는데 많은 부분에서 시행착오가 있었습니다.
실제 프로젝트에 적용하다 보면 이것 외에 더 많은 버그가 있을 수 있지만 우선 공식문서의 예제를 하면서 겪었던 에러에 대해서
알아보았습니다.
잘못된 정보나 추가 질문은 댓글을 남겨 주시기 바랍니다.
'nextjs' 카테고리의 다른 글
nextjs - Amplify 환경변수 설정 (feat. NextAuth) (0) | 2025.01.28 |
---|