프레임워크
- 기존 index, app 파일의 역할은 내부적으로 수행된다.
- 라이브러리는 내가 코드를 사용한다. 프레임워크가 내가 작성한 코드를 사용한다.
pages
- 파일명은 중요하다. url의 이름
- pages 폴더의 컴포넌트명은 중요하지 않다.
- 컴포넌트를 export default 해야 한다.
- 404 페이지가 기본적으로 제공된다.
- 아래와 같이 폴더를 만들 수도 있다.

- React를 import할 필요가 없다. 확장자가 .tsx, .ts가 될 필요도 없다.
Static Pre Rendering
- CSR: “브라우저가 자바스크립트(+ 리액트)를 가져오고, UI를 전부 만든다”
- Next.js: 네트워크가 느리거나, 자바스크립트가 비활성화 되어 있어도 HTML을 볼 수 있다.
- hydration: pre-rendering이 끝난 뒤, 자바스크립트(+ 리액트)가 로드되면 넘겨받아 동작한다.
일반적인 React 앱이 된다.
- Next.js는 React를 백엔드에서 동작시켜서 초기 페이지를 만들고 html에 넣어준다.
그렇기 때문에 유저는 자바스크립트(+ 리액트)가 로드되지 않았더라도 콘텐츠를 볼 수 있다.
Routing
- a 태그를 사용하지 마라. 새로고침 되기 때문이다.
import Link from "next/link" export default function NavBar() { return <nav> <Link href="/"><a>Home</a></Link> <Link href="/about"><a>About</a></Link> </nav> }
Link에는 스타일, 클래스 이름을 적용할 수 없다. 하위 a 태그는 가능하다.
Styles JSX
- Next JS 고유의 방법
- 명시한 스타일은 컴포넌트 내부로 스코프가 제한된다.
import Link from "next/link" import { useRouter } from "next/router" export default function NavBar() { const router = useRouter(); return <nav> <Link href="/"><a className={router.pathname === '/' ? 'active' : ''}>Home</a></Link> <Link href="/about"><a className={router.pathname === '/about' ? 'active' : ''}>About</a></Link> <style jsx>{style}</style> </nav> } const style = ` nav { background-color: tomato } .active { color: yellow } `;
Custom App
App Component
“어떤 컴포넌트의 청사진과 같다”
_app.js
Next.js는 다른 페이지를 렌더링하기 전에 _app.js를 먼저 본다.
전역 스타일을 지정할 수도 있다.
import type { AppProps } from "next/app" import NavBar from "../components/NavBar" export default function App({ Component, pageProps }: AppProps) { return <div> <NavBar /> <Component {...pageProps} /> <style jsx global>{ ` h1 { color: red } ` }</style> </div> }
_app에서는 모든 css를 import할 수 있다. 전역 스타일로 적용된다.
_app을 제외하고, 페이지나 컴포넌트 내에 css를 import하고 싶다면,
그것은 반드시 module이어야 한다.
NavBar를 보여주는 페이지가 있고, 그렇지 않은 경우가 있다.
이것은 어떻게 제어할까?
추가
- _app
서버 요청이 들어왔을 때 가장 먼저 실행되는 컴포넌트.
페이지에 적용할 공통 레이아웃의 역할을 한다.
전역적으로 사용하는 공통 데이터 등을 다루는 곳이다.
용도
- page 이동 중 state를 유지하기 위해 (recoil state 등)
- global css 추가
- _document
_app 다음에 실행되며, 공통적으로 사용할 head나 body 태그 안에 들어갈 내용을 커스텀.
즉, 모든 문서에 공통적으로 적용할 HTML 마크업을 커스텀 하는 곳이다.
용도
- 폰트 import
- charset, 웹 접근성 과니련 태그 설정
- bootstrap, material UI 등 글로벌 커스텀 스타일 ㅅ트 로드
- 글로벌 head 관리
패턴
- Layout 컴포넌트
- Head 컴포넌트 (내장)
Redirects
// next.config.js const API_KEY = process.env.API_KEY; // .gitignore에 포함시키기 const nextConfig = { reactStrictMode: true, async redirects() { return [ { source: '/contact', destination: '/form', permanent: false, }, { source: '/old-blog/:path', destination: '/new-blog/:path', permanent: false, }, ]; }, async rewrites() { return [ { source: '/api/movies', destination: `https://api.themoviedb.org/3/movie/popular?api_key=${API_KEY}`, }, ]; }, };
*을 붙이면 뒤에 붙는 경로들도 캐치할 수 있다.
.env를 gitignore에 포함시켜야 한다.
Rewrites
url이 변경되지 않는다.
타입스크립트
대응 타입들
- getServerSideProps ⇒ GetServerSideProps
- getStaticProps ⇒ GetStaticProps
- getStaticPaths ⇒ GetStaticPaths
GetServerSideProps는 Promise를 반환해야 한다.
타입스크립트
export type GetServerSideProps< P extends { [key: string]: any } = { [key: string]: any }, Q extends ParsedUrlQuery = ParsedUrlQuery, D extends PreviewData = PreviewData > = ( context: GetServerSidePropsContext<Q, D> ) => Promise<GetServerSidePropsResult<P>>
아래와 같이 Promise를 반환하지 않으면 타입 에러가 발생한다.

async를 붙이는 것으로 간단히 해결할 수 있다.
async 함수는 암시적으로 Promise를 사용하여 결과를 반환하기 때문이다.

getServerSideProps는 데이터를 fetch할 때 외에도 사용할 수 있다.