본문 바로가기
C.W.K.
Stream
Lesson 07 of 10 · published

병렬 라우트로 여러 슬롯 그리기

~24 min · parallel routes, @slot, dashboard

Level 0호기심
0 XP0/68 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

한 레이아웃에 독립 화면을 함께 올려

병렬 라우트는 한 레이아웃이 여러 라우트 구간을 동시에 표시하게 해. @analytics처럼 @로 시작하는 폴더가 슬롯이 되고, 레이아웃은 그 이름과 같은 prop을 받아. 기본 children도 하나의 슬롯처럼 동작해.

app/
  layout.tsx          # analytics와 team을 props로 받음
  page.tsx            # 기본 슬롯인 children
  @analytics/
    page.tsx
    loading.tsx
  @team/
    page.tsx
    error.tsx

로딩과 실패도 슬롯마다 갈라져

각 슬롯은 자기 Suspense 경계와 오류 경계를 가질 수 있어. 팀 패널이 먼저 준비되고 분석 패널이 오래 걸려도 둘이 서로를 멈추게 하지 않아. 대시보드처럼 독립적인 영역을 한 화면에 조립할 때 특히 유용해.

default.tsx는 복구 경로야

앱 안에서 부드럽게 이동할 때는 Next.js가 각 슬롯의 현재 상태를 기억할 수 있어. 하지만 주소를 직접 열거나 새로고침하면 어떤 하위 상태를 보여 줘야 하는지 알 수 없는 슬롯이 생겨. 그 슬롯에 default.tsx가 없으면 404가 되므로, 직접 방문해도 성립하는 대체 화면을 반드시 준비해.

병렬 슬롯마다 독립적으로 느려질 수 있는지, 실패해도 다른 슬롯을 쓸 수 있는지 확인해. 둘 다 맞는 대시보드 패널이라면 각자 loading·error·default를 두는 가치가 있어. 새로고침과 앱 내부 이동을 모두 시험해 슬롯의 복구 화면이 실제 맥락을 보존하는지 봐.

한 화면에 여러 영역이 있다고 모두 병렬 라우트인 건 아니야. 같은 데이터와 수명을 공유하는 카드까지 슬롯으로 나누면 폴더와 복구 상태만 늘어. 독립적인 내비게이션 상태나 스트리밍 경계가 필요하지 않다면 일반 컴포넌트 조합이 더 단순해. 한 슬롯을 일부러 느리게 하고 다른 슬롯에서 오류를 던져 각 loading·error 경계가 독립적으로 보이는지 시험해. 앱 내부 이동 뒤 새로고침하고 주소를 직접 붙여 넣어 default.tsx가 없는 경우의 404와 준비한 대체 화면을 비교해.

슬롯마다 접근성 landmark와 제목을 독립적으로 제공해 스트리밍 순서가 달라도 문서 구조가 이해되게 해. 시각적으로 나란한 패널이 DOM 도착 순서 때문에 screen reader에서 엉키지 않는지도 봐.

Code

레이아웃에서 슬롯 조합하기·tsx
// app/layout.tsx
export default function Layout({
  children,
  analytics,
  team,
}: {
  children: React.ReactNode;
  analytics: React.ReactNode;
  team: React.ReactNode;
}) {
  return (
    <div className="grid grid-cols-3 gap-6 p-6">
      <section className="col-span-2">{children}</section>
      <aside className="space-y-4">
        {analytics}
        {team}
      </aside>
    </div>
  );
}
슬롯별 로딩 화면·tsx
// app/@analytics/loading.tsx
export default function AnalyticsLoading() {
  return <div className="h-40 animate-pulse rounded-lg bg-gray-100" />;
}

// app/@analytics/page.tsx
export default async function Analytics() {
  const stats = await getAnalytics(); // 느림
  return <AnalyticsPanel stats={stats} />;
}
기본 대체 화면으로 404 막기·tsx
// app/@analytics/default.tsx
export default function Default() {
  return null; // 또는 대체 화면
}

External links

Exercise

대시보드 레이아웃에 @analytics 슬롯과 loading.tsx를 추가해. 분석 데이터가 끝나기 전에 기본 페이지가 먼저 렌더링되는지 network에서 확인해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.