본문 바로가기
PROJECT

[웹 포트폴리오 만들기] 5편 - next로 모달 라우팅 구현하기

by 3급우사기 2024. 5. 21.

2024.04.12 - [PROJECT] - [웹 포트폴리오 만들기] 1편 - 디자인 구상하기

2024.04.23 - [PROJECT] - [웹 포트폴리오 만들기] 2편 - NEXT 로딩화면 구현하기

2024.05.07 - [PROJECT] - [웹 포트폴리오 만들기] 3편 - 디자인 갈아엎기

2024.05.08 - [PROJECT] - [웹 포트폴리오 만들기] 4편 - fullpage 구현하기

2024.05.31 - [PROJECT] - [웹 포트폴리오 만들기] 6편 - 모바일 반응형 구현과 ..최종 완성

Intercepting Routes와 Parallel Routes을 이용해서 모달창 만들기

웹앱에서 모달창 만들 때 Intercepting Routes랑 Parallel Routes 쓰면 사용자 경험도 상승하고 모달마다 주소 다르게 줄 수 있음. 이러면 모달창을 앱 내에서 탐색할 때는 모달로, 페이지 새로고침하면 독립형 페이지로 렌더링 가능함.

 

나는 포폴 프로젝트 목록에서 클릭하면 각 프로젝트의 자세한 설명을 모달로 띄울 때 이 방법으로 했음

 

Parallel Routes 설명

 

Parallel Routes는 같은 레이아웃에서 여러 페이지를 동시에 또는 조건부로 렌더링 가능함. 대시보드나 소셜 사이트 피드 같은 동적인 섹션에 많이 씀. 예를 들어 대시보드 주 콘텐츠랑 사이드바를 동시에 렌더링하거나 피드랑 상세보기 페이지를 병렬로 렌더링할 수 있음.

 

Intercepting Routes 설명

 

Intercepting Routes 쓰면 현재 레이아웃에서 앱 다른 부분 경로를 로드 가능함. 이건 사용자가 다른 컨텍스트로 전환 안 해도 경로 콘텐츠를 볼 수 있게 해줌. 예를 들어 피드에서 사진 클릭하면 사진을 모달로 띄워서 피드 위에 오버레이 가능함. 이 경우 Next.js는 /photo/123 경로 가로채서 URL 마스킹하고 /feed 위에 오버레이함.

 

코드 예제


다음은 Next.js에서 Intercepting Routes랑 Parallel Routes로 모달 구현한 예제임.

파일 구조는 여기를 많이 참고함

파일 구조



app/@modal/(...)detail/[id]/page.tsx

"use client";
import React, { useEffect } from "react";
import ProjectDetail from "../../../../components/detail";

function pagemodal({ params: { id } }: { params: { id: string } }) {
  useEffect(() => {
    document.body.style.overflow = "hidden";
    return () => {
      document.body.style.overflow = "auto";
    };
  }, []);
  return <ProjectDetail projectId={parseInt(id)}></ProjectDetail>;
}

export default pagemodal;

프로젝트 설명을 띄우는 모달창.

detail/[id]에서 가로채서 이 화면을 띄움

 

app/@modal/default.tsx, app/default.tsx.

export default function Default() {
  return null;
}

Parallel Routes의 대체 페이지
모달 경로가 아닐 때 기본적으로 표시되는 페이지.

이거 없으면 에러남

 

app/detail/[id]/page.tsx

"use client";
import React, { useEffect } from "react";
import ProjectDetail from "../../../components/detail";
import styles from "../../../styles/detail.module.css";
import projectslist from "../../../public/data";
import Link from "next/link";
import { useRouter } from "next/navigation";

function pagenomodal({ params: { id } }: { params: { id: string } }) {
  const project = projectslist.find((project) => project.id === parseInt(id));
  const router = useRouter();
  if (!project) {
    return (
      <div className={styles.container}>
        <div>프로젝트를 찾을 수 없습니다.</div>;
      </div>
    );
  }
  return (
    <div className={styles.projectBodyNoModal}>
    // 프로젝트 설명하는 페이지
        </div>
  );
}

export default pagenomodal;

모달 창에서 새로고침한 경우 표시되는 페이지
사용자가 모달 창에서 새로고침하거나 직접 URL을 입력해 접근할 때, 독립형 페이지로서 렌더링된다.

 

app/layout.tsx

"use client";
import { useEffect, useState } from "react";
import Header from "../components/header";
import "../styles/global.css";
import Loading from "./loadingWindow";

export default function RootLayout({
  children,
  modal,
}: {
  children: React.ReactNode;
  modal: React.ReactNode;
}) {
  const [isloading, setisLoading] = useState(true);

  useEffect(() => {
    setisLoading(false);
  }, []);
  return (
    <html lang="en">
      <body>
        <Loading isloading={isloading} />
        <Header />
        {children}
        {modal}
      </body>
    </html>
  );
}

레이아웃 파일

 

 

새로고침 시 모습

 

구조가 복잡해서 헷갈렸는데 아래 깃허브링크 참고해서 천천히 따라하니 구현할수있었다!

 

 

참고 

https://github.com/vercel/nextgram

 

GitHub - vercel/nextgram: A sample Next.js app showing dynamic routing with modals as a route.

A sample Next.js app showing dynamic routing with modals as a route. - vercel/nextgram

github.com

https://nextjs.org/docs/app/building-your-application/routing/intercepting-routes

 

Routing: Intercepting Routes | Next.js

Use intercepting routes to load a new route within the current layout while masking the browser URL, useful for advanced routing patterns such as modals.

nextjs.org

https://nextjs.org/docs/app/building-your-application/routing/parallel-routes

 

Routing: Parallel Routes | Next.js

Simultaneously render one or more pages in the same view that can be navigated independently. A pattern for highly dynamic applications.

nextjs.org