[Next.js] Page Router - 페이지 라우팅, 네비게이팅

Yeonju·2025년 1월 15일

Next.js

목록 보기
2/10

Page Router

많은 기업에서 사용되고 있는 안정적인 라우터로, React Router처럼 페이지 라우팅 기능 제공한다.
pages폴더 아래에 들어있는 폴더/파일명 기반의 라우팅 규칙을 따른다.


프로젝트 시작하기

npx create-next-app@14 [패키지명]

npx : Node Package Executor로, npm의 최신 버전을 설치 없이 사용할 수 있다.
create-next-app : next.js 앱을 생성하는 CLI 명령어
@14 : 사용할 next.js 버전을 지정한다. Page Router를 사용하기 위해 최신 버전이 아닌 14버전을 선택한다.


would you likte to use 'TypeScript'? ... No / 'Yes'
would you likte to use 'ESLint'? ... No / 'Yes'
would you likte to use 'Tailwind CSS'? ... 'No' / Yes
would you likte to use `src/` directory? ... No / 'Yes'
would you likte to use 'App Router?' (recommended) ... 'No' / Yes
would you likte to customize the default import alias (@/*)? ... 'No' / Yes

ESLint : ECMAScript + Lint의 약자로, 표준 avaScript 문법 및 코드 스타일 에러를 확인하고 수정하는 도구이다.
App Router : Page Router를 사용한다면 선택하지 않는다.
alias 설정 커스터마이징 : 절대 경로를 편하게 사용할 수 있게 해주는 alias를 커스터마이징 할건지 여부 (기본: @/...)


기본적으로 생성되는 파일

✨_app.tsx

import "@/styles/globals.css";
import type { AppProps } from "next/app";

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

모든 페이지 역할을 하는 컴포넌트들의 부모 컴포넌트로 ROOT 컴포넌트 역할을 한다.

2개의 Props를 받는다.

Component : 현재 페이지 역할을 할 컴포넌트
pageProps : 현재 페이지 역할을 할 컴포넌트에 전달될 Props들을 모두 객체로 보관한 것

return -> Page 역할을 할 Component를 렌더링하면서 pageProps를 구조 분해 할당하여 전달

import "@/styles/globals.css";
import type { AppProps } from "next/app";

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

따라서 위와 같이 글로벌 헤더를 추가하는 등의 조작도 가능하다.

✨_document.tsx

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

export default function Document() {
  return (
    <Html lang="en">
      <Head />
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

모든 페이지에 공통적으로 적용되어야하는 Next앱의 HTML 코드를 설정하는 컴포넌트로, 기존 React 앱의 index.html과 비슷한 역할을 한다.

meta 태그, 폰트, character set, 서드파티 스크립트 설정 등 모든 페이지에 설정되어야 하는 html 태그를 관리하기 위해 사용한다.

✨next.config.mjs

/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
};

export default nextConfig;

next 앱의 설정을 관리하는 파일

reactStrictMode : react앱에서 발생하는 잠재적 문제를 검사하기 위해 개발 모드로 실행했을 때 컴포넌트를 2번 실행한다. 귀찮으니 false로 해주기


페이지 라우팅

✨기본 폴더 구조

Next.js에서는 pages 폴더 구조에 따라 자동으로 라우팅이 설정된다.

단일 파일 기반 라우팅

src
├─ pages
│  ├─ book.tsx    	    ->  "/book" 경로에 매핑
│  └─ index.tsx   	    ->  "/" 경로에 매핑
...

폴더 기반 라우팅

src
├─ pages
│  ├─ book
│  │  └─ index.tsx      ->  "/book" 경로에 매핑
│  └─ index.tsx         ->  "/" 경로에 매핑
...

✨동적 경로 (Dynamic Routes)

가변적인 값을 포함하는 경로를 말한다. 블로그 게시물, 상품 상세 페이지 처럼 ID 또는 슬러그(slug)를 사용하는 페이지에 적합하다.

파일명

[id].tsx
[]안의 값이 동적으로 매핑된다.

예시

book
└─ [id].tsx

https.../book/123
-> 123id에 매핑된다.

https.../book/123/456
-> 404 not found 에러가 발생한다.

✨Catch All Segment

Catch All Segment는 여러 경로 세그먼트를 처리할 수 있다.

파일명

[...id].tsx
-> ...은 하나 이상의 세그먼트를 처리할 수 있음을 나타낸다.

예시

book
└─ [...id].tsx

https.../book/123/456/7/8/9...
-> 404 not found 에러가 발생하지 않는다.
id 값이 {123, 456, 7, 8, 9} 형태의 배열로 저장된다.

book 디렉터리 아래에 index.tsx가 없는 경우, https.../book/ 주소를 입력했을 때
-> 404 not found 에러가 발생한다.

✨Optional Catch All Segment

Optional Catch All Segment는 index 역할까지 포함하는 동작을 제공합니다.

파일명

[[...id]].tsx
-> 대괄호 [[ ]]를 사용해 값이 없을 경우에도 처리한다.

예시

book
└─ [[...id]].tsx

https://.../book/
-> book 디렉터리 아래에 index.tsx가 없어도, 404 not found 에러가 발생하지 않는다.


네비게이팅

페이지를 이동시키는 것

✨a 태그

import "@/styles/globals.css";
import type { AppProps } from "next/app";

export default function App({ Component, pageProps }: AppProps) {
  return (
    <>
      <header>
        <a href={"/">index</a>
      </header>
      <Component {...pageProps} />
    </>
  );
}

a태그를 사용하는 경우 CSR 방식이 아닌 SSR 방식으로 동작하며, 서버에 매번 새로운 페이지를 요청한다. 페이지가 전환될 때 전체 HTML을 다시 요청하므로, 페이지 전체를 다시 렌더링한다.

  • 유용한 상황: 외부 링크를 연결할 때, CSR을 사용할 필요가 없을 때
import "@/styles/globals.css";
import type { AppProps } from "next/app";
import Link from "next/link";

export default function App({ Component, pageProps }: AppProps) {
  return (
    <>
      <header>
        <Link href={"/"}>index</Link>
      </header>
      <Component {...pageProps} />
    </>
  );
}

Link 태그를 사용하면 CSR 방식으로 렌더링이 이루어진다. 기본적인 사용 방법은 a 태그와 동일하다.

  • 유용한 상황: 내부 링크를 연결할 때

✨useRouter로 이벤트 헨들링

import "@/styles/globals.css";
import type { AppProps } from "next/app";
import Link from "next/link";
import { useRouter } from "next/router";

export default function App({ Component, pageProps }: AppProps) {
  const router = useRouter();

  const onClickButton = () => {
    router.push("/search");
  };

  return (
    <>
      <header>
        <div>
          <button onClick={onClickButton}>/search 페이지로 이동</button>
        </div>
      </header>
      <Component {...pageProps} />
    </>
  );
}

useRouter 훅을 사용하여 프로그래밍 방식으로 페이지 이동을 제어할 수 있다.

  • 유용한 상황: 이벤트 기반으로 페이지 이동을 제어해야 할 때

useRouter 메서드

push("url") : 특정 경로로 이동하며, 히스토리 스택에 기록을 추가한다
replace("url") : 히스토리 스택을 덮어쓰며 뒤로가기를 방지한다
back() : 이전 페이지로 이동한다

profile
햄스터와 개발을 좋아합니다.

0개의 댓글