[Next.js] Page Router 구조와 라우팅 방식 이해

질문Bot·2025년 4월 23일

Next.js

목록 보기
2/13
post-thumbnail

이번 글에서는 Next.js의 Page Router 방식에 대해 공부하면서 정리하려고합니다.

"근데 이제는 App Router 쓰는 거 아니야?"라고 생각하실 수도 있습니다.
👍 맞습니다. 최신 Next.js에서도 App Router가 권장되는것을 확인할수있습니다.

하지만 여전히 많은 기업과 팀에서는 Page Router를 기반으로 한 기존 서비스를 운영하고 있고,
이 구조에 대한 이해는 필수적이라고 생각을 합니다.

또한 Page Router를 제대로 이해하면, App Router의 구조와 장점이 왜 등장했는지도 더 명확하게 이해할 수 있다고 판단하였습니다.


👋🏻 라우터 종류

Next.js는 두 가지 라우팅 방식이 존재합니다.

1. Page Router – 기존 방식인 (pages 디렉토리 기반)
2. App Router – 최신 방식인 (app 디렉토리 기반, Next.js 13 이상)


⭐️ Router 처리 예시

Next.js의 Page Router는 React Router처럼 파일 기반의 라우팅 시스템을 제공합니다.
즉, pages 폴더 안의 파일 이름만으로 자동으로 라우팅이 처리됩니다

📄 기본 pages로 라우터 처리 (파일)

pages/ 폴더 아래에 있는 파일의 이름이 곧 라우터 경로가 됩니다.

pages에 파일로만 라우터 맵핑
pages
├── index.tsx  
├── about.tsx  
└── profile.tsx

정리해보면 이렇게 router처리가 된다고 알수있습니다.

  • / → index.tsx
  • /about → about.tsx
  • /profile → profile.tsx

🗂️ pages로 라우터 처리 (폴더)

하지만 컴포넌트 방식을 사용하다보면 사실 pages에 파일로 있는것은 말이 안되긴하죠??
컴포넌트 분리를 위해 폴더 단위로도 당연히 라우터를 구성할 수 있습니다.

pages에 폴더 라우터 맵핑
pages
├── index.tsx
├── about
│	└── index.tsx
└── profile
	└── index.tsx
  • /about → about/index.tsx
  • /profile → profile/index.tsx
    이와같이 폴더 단위로 컴포넌트를 관리하는게 훨씬 더 유지보수에 편합니다.

🔁 pages로 동적 라우터 처리

Velog 사이트 기준으로 예시를 들어보겠습니다 :
Ex) /유저ID/게시글제목 형태의 URL이 필요한 경우, 동적 라우팅을 사용할 수 있습니다.
Next.js에서는 [] 대괄호를 사용해 URL 파라미터를 받습니다.

pages에 파일로만 라우터 맵핑
pages/
├── [userId]
    └── [title].tsx
  • /minji/react-hooks → userId = "minji", title = "react-hooks"

그리고 그 파라미터는 아래와 같이 컴포넌트에서 활용이 가능합니다.

//pages/[userId]/[title].tsx

import { useRouter } from 'next/router';

export default function Test() {
  const { userId, title } = useRouter().query;

  return (
    <div>
      <h1>제목 : {title}, 유저 : {userId}</h1>
    </div>
  );
}

➕ 추가 내용 ➕ catch all segments

pages/[userId]/[title].tsx
위에는 이렇게 되어있습니다. 그래서 /userId자리/title자리 이렇게 처리 가능했습니다.

근데 /userId자리/title1/title2/title3 이렇게 들어온다면 가능할까요?
그때는 catch all segments를 사용해야합니다.
❌ pages/[userId]/[title].tsx
✅ pages/[userId]/[...title].tsx
이렇게 변경해줘야합니다.

이렇게 하면 title을 useRouter로 출력해보면
[title1,title2,title3 ...] 이와 같이 배열 형태로 저장이 되어있습니다.

➕ 추가 내용 ➕ Optional catch all segment

이건 무엇이냐?
pages/[userId]/[...title].tsx 이렇게 정의하면
pages/userId 이렇게 title자리를 주지 않았을때 404가 나오게 됩니다.

방법
1. pages/[userId]/index.tsx 만든다. 그러면 이 index가 나오게 됩니다. (근데 나는 title.tsx안에 로직을 쓰고싶은데?
2. pages/[userId]/[[...title].tsx] 이것이 optional catch all segment입니다. title의 값이 있을때도, 없을때도 다 처리 가능한 옵션입니다.


🧩 Page router 프로젝트 구성

처음 npm-create-next-app을 통해 next를 생성하였습니다.
이번은 page router에 대해서 학습하기 위해 app router대신 page router를 선택해서 생성하였습니다.

page router 프로젝트 기본세팅 구조입니다.


🗂️ _app.tsx

_app.tsx는 모든 페이지의 공통 부모 컴포넌트입니다.
React의 App.tsx와 동일한 역할을 수행하며, 전역 상태 관리나 레이아웃 적용 시 주로 사용한다고 생각하시면 됩니다.

✔️ _app.tsx [코드]

export default function App({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />;
}

✔️ _app.tsx [props]

App의 두개의 props가 존재합니다. Component와 pageProps

  • Component props는 현재 페이지입니다.
  • pageProps는 그 페이지의 내려주는 props를 객체로 담아주는것입니다.

✔️ 개발자 도구 확인

개발자 도구에서 component를 확인해보면 이렇게 App/Test.tsx가 온것을 확인할수 있습니다.


🗂️ _document.tsx

document 파일은 아마 내부 코드를 보시면 대략 아실수있습니다.
이 프로젝트에 공통적으로 적용되는 HTML파일입니다.
index.tsx라고 생각해도 될거같습니다.

import { Html, Head, Main, NextScript } from "next/document";

export default function Document() {
  return (
    <Html lang="en">
      <Head />
      <body className="antialiased">
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}
  • 메타 태그 설정
  • GA 추가
  • Font 설정
    등의 HTML 태그들을 관리하는 파일이라고 생각하시면 됩니다.

🗂️ next.config.ts

next 프로젝트의 설정을 담당하는 파일입니다.

reactStrictMode는 컴포넌트 랜더링을 두번 시키기 때문에 지금 실습과정에서 필요없어 false로 진행합니다.

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  /* config options here */
  reactStrictMode: false,
};

export default nextConfig;

왜 Next에서는 a태그 대신 Link태그를 사용할까요?

서비스 마운트시 서버 사이드 랜더링을 통해 생성된 HTML 받아와 화면에 보여주게 됩니다.
이후 Link를 통해 다른 페이지 이동을 할 때는 클라이언트 사이드 랜더링 방식을 진행하게 됩니다.
즉, 브라우저는 전체 페이지를 다시 로드하지 않고, 변경된 부분만 동적으로 렌더링합니다.
페이지 이동 시간이 빨라 UX측면에서 좋습니다.

❌ a tag :

url에 직접 접근하는 방식을 사용하고있습니다. 그래서 들어갈때마다 서버로 부터 html파일을 다시 받고, 다시 보여주는 형식을 진행하고있습니다.

그래서 a보단 Link를 통해 활용하는것이 Next.js의 장점을 살릴수있는 방법입니다.
하지만 외부 서비스로 네이게이트를 진행할 시 a와 Link는 동일합니다.

profile
유용한 정보를 전달하는 사람이 되고자 노력합니다.

0개의 댓글