Next.js의 동적 페이지 처리

Next.js는 파일 기반 라우팅(file-based routing) 시스템을 제공하는 React 프레임워크입니다. 특히 동적 페이지(dynamic routing) 기능은 실제 서비스에서 매우 자주 사용됩니다.
이번 글에서는 포트폴리오 상세 페이지를 구현한 실제 예시 코드를 바탕으로 Next.js의 동적 페이지 처리 방식의 구조와 동작 원리를 자세히 설명하겠습니다.


📁 프로젝트 구조

PORTFOLIO-APP/
├── backend/
│   ├── models/
│   ├── routes/
│   ├── schemas/
│   ├── db.py
│   ├── main.py
│   └── requirements.txt
│
├── frontend/
│   ├── pages/
│   │   ├── portfolio/
│   │   │   └── [portfolioId].tsx   # ✅ 동적 라우팅 페이지
│   ├── components/
│   ├── lib/
│   ├── styles/
│   └── package.json
│
├── docker-compose.yml
└── package.json

이 프로젝트에서 핵심은 /pages/portfolio/[portfolioId].tsx 파일입니다.
[portfolioId]Next.js의 동적 경로(Dynamic Route) 문법으로, URL의 파라미터를 페이지 컴포넌트에 전달합니다.


🔍 Next.js의 라우팅 기본 구조

Next.js는 pages/ 디렉토리를 기준으로 URL 경로를 자동으로 매핑합니다.
즉, 별도의 react-router 설정이 필요 없습니다.

예를 들어 다음과 같은 구조를 보세요.

/pages/
├── index.tsx         →  /
├── about.tsx         →  /about
└── portfolio/
    └── [portfolioId].tsx  →  /portfolio/1, /portfolio/2, ...
  • index.tsx → 루트 URL(/)
  • about.tsx/about
  • [portfolioId].tsx동적 경로 (/portfolio/:id 형태)

즉, pages 폴더의 구조가 곧 라우팅 구조가 됩니다.
이것이 Next.js가 **파일 기반 라우팅(file-based routing)**이라고 불리는 이유입니다.


⚙️ 동적 라우팅(Dynamic Routing)이란?

**동적 라우팅(Dynamic Routing)**이란
URL의 특정 구간이 변수처럼 동작하여 여러 개의 페이지를 하나의 파일로 처리하는 기능을 의미합니다.

예를 들어 /portfolio/1, /portfolio/2, /portfolio/3 등 여러 페이지가 있을 때,
이를 각각 파일로 만들지 않고 하나의 [portfolioId].tsx 파일로 처리할 수 있습니다.

/pages/portfolio/[portfolioId].tsx

Next.js는 이 파일을 읽을 때 [portfolioId] 부분을 URL 파라미터 변수로 인식합니다.


🧭 useRouter()로 동적 파라미터 가져오기

Next.js는 next/router 패키지의 useRouter() 훅을 통해
현재 페이지의 라우팅 정보에 접근할 수 있도록 제공합니다.

import { useRouter } from "next/router";

export default function PortfolioDetail() {
  const router = useRouter();
  const { portfolioId } = router.query;

  return <h1>Portfolio ID: {portfolioId}</h1>;
}

router.query 객체에는 URL에 포함된 모든 파라미터가 담깁니다.
예를 들어 /portfolio/10으로 접근하면 portfolioId"10"이 됩니다.

즉, Next.js는 파일명 → URL 파라미터 → 컴포넌트 props로 연결되는 일련의 과정을 내부적으로 수행합니다.


🔄 내부 동작 흐름 이해하기

Next.js가 동적 라우트를 처리하는 흐름은 아래와 같습니다.

  1. 사용자가 /portfolio/3 URL에 접근
  2. Next.js 라우터는 /pages/portfolio/[portfolioId].tsx 파일을 탐색
  3. [portfolioId]라는 변수명을 인식하고 router.query.portfolioId = "3"으로 전달
  4. 해당 컴포넌트를 렌더링하고, 필요한 데이터(API 등)를 요청
  5. 화면에 “Portfolio ID: 3”과 같은 결과 출력

이 전체 과정은 클라이언트 측에서 수행될 수도 있고(클라이언트 사이드 렌더링, CSR),
서버에서 사전에 HTML을 생성한 뒤 전달할 수도 있습니다(서버사이드 렌더링, SSR).


🧠 포트폴리오 상세 페이지 구조 분석

아래는 실제 구현 코드입니다. Mantine UI와 axios를 조합하여 데이터 조회, 수정, 삭제, 대시보드 계산 기능을 제공합니다.

export default function PortfolioDetail() {
  const router = useRouter();
  const { portfolioId } = router.query;
  const [portfolioName, setPortfolioName] = useState("");
  const [assets, setAssets] = useState<Asset[]>([]);
  const [deposits, setDeposits] = useState<Deposit[]>([]);
  
  // 포트폴리오 상세 조회
  useEffect(() => {
    if (!portfolioId) return;
    const fetchPortfolioDetails = async () => {
      const response = await callApi.get(`/portfolios/${portfolioId}`);
      setPortfolioName(response.data.name);
    };
    fetchPortfolioDetails();
  }, [portfolioId]);
}

위 코드에서는 portfolioId가 존재할 때 백엔드 API(/portfolios/:id)를 호출하여 데이터를 로드합니다.
useEffect 훅을 사용해 라우팅 파라미터가 변경될 때마다 데이터를 새로 가져오도록 설정했습니다.

포트폴리오 상세 화면 캡처

💡 Next.js 동적 페이지의 장점

  1. 직관적인 URL 설계
    /portfolio/[id]와 같은 구조로 각 리소스의 고유 주소를 명확히 표현할 수 있습니다.
  2. SEO 친화적 구조
    동적 페이지는 SSR(서버사이드 렌더링)과 조합하면 검색 엔진이 콘텐츠를 쉽게 크롤링할 수 있습니다.
  3. 컴포넌트 재사용성 극대화
    동적 페이지 내부에서도 공통 탭, 카드, 데이터 로직 등을 모듈화하여 유지보수성을 높입니다.
  4. API 중심의 유연한 데이터 처리
    FastAPI와 연동하여 CRUD를 처리하면서 프론트엔드 단에서는 API 호출만으로 다양한 데이터를 표시할 수 있습니다.

🧩 정리

이번 글에서는 Next.js의 동적 페이지 처리를 중심으로 실제 프로젝트 구조와 코드를 분석했습니다.
특히 /pages/portfolio/[portfolioId].tsx 파일을 통해,
Next.js의 파일 기반 라우팅과 동적 파라미터 처리 방식, 그리고 API 데이터 연동 구조를 살펴봤습니다.

Next.js의 동적 라우팅은 단순하지만 강력한 설계를 제공하며,
대규모 프로젝트에서도 확장성과 유지보수성을 높이는 핵심 기능입니다.


📚 참고

댓글 남기기