GitHub
©-2 kd02109 All rights reserved.

Next.js Parallel Routes && Intercepting Routes

  • nextJs
January 6, 2024

Parallel Routing

Parallel Routing 은 하나의 레이아웃에서 두개 이상의 페이지를 rendering 하기 위해 사용됩니다. web app을 다이나믹하게 사용하기 위해서 하나의 레이아웃에서 두 개 이상의 페이지를 렌더링 할 수 있습니다.

Parallel Routing을 사용하기 위해서는 layout.tsx의 위치와 Parallel Routing을 적용하는 페이지의 위치가 중요합니다. 즉 같은 폴더 내에 Parallel Routing 폴더와 layout.tsx가 위치해야 합니다.

아래의 폴더구조는 logout인 유저가 main page에서 login page와 signup page를 모달 형식으로 하나의 페이지에서 띄우고자 합니다.

📦(logout)
 ┣ 📂@modal
 ┃ ┣ 📂(.)i
 ┃ ┃ ┗ 📂flow
 ┃ ┃ ┃ ┣ 📂login
 ┃ ┃ ┃ ┃ ┣ 📜page.module.css
 ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┗ 📂signup
 ┃ ┗ 📜default.tsx
 ┣ 📂i
 ┃ ┗ 📂flow
 ┃ ┃ ┣ 📂login
 ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┗ 📂signup
 ┃ ┃ ┃ ┗ 📜page.tsx
 ┣ 📂login
 ┃ ┗ 📜page.tsx
 ┣ 📜layout.tsx
 ┗ 📜page.tsx

이때 layout.tsx를 다음과 같이 설정합니다.

//  ./src/app/(logout)/layout.tsx
 
import type { Metadata } from 'next';
import style from '@/app/page.module.css';
export const metadata: Metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
};
 
export default function RootLayout(props: {
  children: React.ReactNode;
  modal: React.ReactNode;
}) {
  return (
    <main className={style.main}>
      {props.children}
      {props.modal}
    </main>
  );
}

추가로 Parallel Routing을 적용해야 하는 routing folder에 @filename으로 이름을 지어야 합니다.

default.tsx

Next.js가 현재 URL을 기반으로 슬롯의 활성 상태를 복구할 수 없을 때 대체 파일로 렌더링할 default.js 파일을 정의할 수 있습니다.

새로 고침 시 Next.js는 먼저 일치하지 않는 슬롯의 default.js 파일을 렌더링하려고 시도합니다. 해당 파일을 사용할 수 없는 경우 404가 렌더링됩니다.

Example Modals

Next.js에서 Parallel Routing의 주된 사용 방법으로 Modal 렌더링을 소개하고 있습니다.

이때 모달이 활성화되어 있지 않을 때 모달의 콘텐츠가 렌더링되지 않도록 하려면 null을 반환하는 default.js 파일을 만들면 됩니다.

export default function Default() {
  return null;
}

만약 모달을 닫기를 원한다면, router.back() 메서드를 활용해서 모달을 닫을 수 있습니다.

Intercepting Routes

Intercepting Routes는 화면을 가로챕니다. 트위터(X)에서 “로그인” 혹은 “회원가입” 버튼을 클릭할 경우 “/”에서 “/i/flow/login” 혹은 “/i/flow/logout”으로 이동합니다. 이때 각각에 해당하는 모달 폼을 띄웁니다. 이때 배경 화면은 메인 화면을 유지하고 있습니다. 하지만 위의 Parallel routes만을 적용할 경우 모달을 띄울 때, 배경은 빈 화면이 됩니다. X는 이와 달리 메인 화면이 유지되고 있습니다. 하지만 새로고침 할 경우, 메인화면 없이 각각 로그인, 회원가입 모달 창만 띄우게 됩니다.

아래 X(twitter)의 메인 페이지의 동작방식을 보면 이해하기 쉬울 것 같습니다.

img

Next.js에서 해당 기능을 구현하려면 어떻게 해야할까? 고민하는 와중에 **Intercepting Routes**가 있었습니다. 현재 레이아웃 내에서 애플리케이션의 다른 부분에서 경로를 로드할 수 있습니다. 이 라우팅 패러다임은 사용자가 다른 컨텍스트로 전환하지 않고도 경로의 콘텐츠를 표시하려는 경우에 유용할 수 있습니다. 따라서 모달창을 띄울 경우, 배경화면을 유지(가로채기)하고 변경된 라우팅의 페이지를 띄울 수 있습니다.

Intercepting routes는 (..)으로 이름이 시작해야 합니다.

  • (.) 같은 경로 레벨**
  • (..) 해당 경로에서 한 단계 위의 경로**
  • (..)(..)해당 경로에서 두 단계 위의 경로**
  • (...) app directory를 가로챕니다.**

정리

따라서 Intercepting routes를 통해 화면을 가로채서 모달 뒤의 화면을 채울 수 있습니다. Parallel Routes를 활용해서는 url 이동이 있는 모달을 띄울 수 있습니다.

새로 고침 시에 뒤 배경이 빈 화면이 되고 로그인, 회원가입 페이지만 남는 이유는 Next.js의 Link 태그를 통해 CSR 방식으로 페이지를 로드하지 않기 때문입니다. 즉 새로고침시에 Next.js는 입력된 URL에 맞추어 SSR로 동작합니다. 따라서 Intercepting routes, Parallel Routes가 정상적으로 동작하지 않고 기존에 같은 이름으로 적용한 라우터가 동작합니다.

📦(logout)
 ┣ 📂@modal
 ┃ ┣ 📂(.)i   -> Link 태그를 통해 Intercepting routes, Parallel Route 동작
 ┃ ┃ ┗ 📂flow
 ┃ ┃ ┃ ┣ 📂login
 ┃ ┃ ┃ ┃ ┣ 📜page.module.css
 ┃ ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┃ ┗ 📂signup
 ┃ ┗ 📜default.tsx
 ┣ 📂i  -> 새로고침 시에 해당 경로에서 정적 페이지를 불러옵니다.
 ┃ ┗ 📂flow
 ┃ ┃ ┣ 📂login
 ┃ ┃ ┃ ┗ 📜page.tsx
 ┃ ┃ ┗ 📂signup
 ┃ ┃ ┃ ┗ 📜page.tsx
 ┣ 📂login
 ┃ ┗ 📜page.tsx
 ┣ 📜layout.tsx
 ┗ 📜page.tsx

참조

  • Next.js Parallel Routes
  • Next.js Intercepting Routes
Content Table
  • Parallel Routing
  •    - default.tsx
  •    - Example Modals
  • Intercepting Routes
  • 정리
  • 참조
MSW(Mocking Service Worker)
React Query SSR