많은 기업에서 사용되고 있는 안정적인 라우터로, 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를 커스터마이징 할건지 여부 (기본: @/...)
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} />
</>
);
}
따라서 위와 같이 글로벌 헤더를 추가하는 등의 조작도 가능하다.
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 태그를 관리하기 위해 사용한다.
/** @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 -> "/" 경로에 매핑
...
가변적인 값을 포함하는 경로를 말한다. 블로그 게시물, 상품 상세 페이지 처럼 ID 또는 슬러그(slug)를 사용하는 페이지에 적합하다.
[id].tsx
[]안의 값이 동적으로 매핑된다.
book
└─ [id].tsx
https.../book/123
-> 123이 id에 매핑된다.
https.../book/123/456
-> 404 not found 에러가 발생한다.
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는 index 역할까지 포함하는 동작을 제공합니다.
[[...id]].tsx
-> 대괄호 [[ ]]를 사용해 값이 없을 경우에도 처리한다.
book
└─ [[...id]].tsx
https://.../book/
-> book 디렉터리 아래에 index.tsx가 없어도, 404 not found 에러가 발생하지 않는다.
페이지를 이동시키는 것
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을 다시 요청하므로, 페이지 전체를 다시 렌더링한다.
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 태그와 동일하다.
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 훅을 사용하여 프로그래밍 방식으로 페이지 이동을 제어할 수 있다.
push("url"): 특정 경로로 이동하며, 히스토리 스택에 기록을 추가한다
replace("url"): 히스토리 스택을 덮어쓰며 뒤로가기를 방지한다
back(): 이전 페이지로 이동한다