
Next.js 13, Pages Router 을 기준으로 작성되었습니다.
pages/index.tsx 라는 파일은 /에 접속했을 때 반환하는 페이지를 구현한 것이다.pages/sample.tsx를 작성하고 npm run dev로 개발 서버를 실행하면 localhost:3000/sample 이라는 URL로 접근할 수 있다.function sample() {
return (
<div>sample 페이지 입니다.</div>
)
}
export default sample

npm run build

| 종류 | 데이터 취득에 사용하는 주요 함수 | 데이트 취득 시점 | |
|---|---|---|---|
| SSG | getStaticProps | 빌드 시(SSG) | 데이터 취득을 전혀 수행하지 않는 경우도 SSG에 해당 |
| SSR | getServerSideProps | 사용자 요청 시(서버 사이드) | getInitialProps를 사용해도 SSR |
| ISR | revalidate를 반환하는 getStaticProps | 빌드 시(ISR) | ISR은 배포 후에도 백그라운드 빌드가 실행된다. |
| CSR | 그 밖의 임의의 함수(useSWR 등) | 사용자 요청 시(브라우저) | CSR은 SSG/SSR/ISR 과 동시에 사용 가능 |
NextPage 는 pages를 위한 타입NextPage<Props> 와 같이 지정import { NextPage } from 'next' // 타입을 위해 도입
import Head from 'next/head' // Next.js의 내장 컴포넌트
// 페이지 컴포넌트의 props 타입 정의
type SSGProps = {}
// SSG용 페이지 구현
// NextPage는 Next.js의 Pages용 타입
// NextPage<props>에서 props가 들어가는 Page임을 명시
const SSG: NextPage<SSGProps> = () => {
return (
<div>
{/* Head 컴포넌트로 감싸면, 그 요소는 <head> 태그에 배치됨 */}
<title>Static Site Generation</title>
<link rel="icon" href="/favicon.io" />
<main>
<p>
이 페이지는 정적 사이트 생성을 통해 빌드 시 생성된 페이지입니다.
</p>
</main>
</div>
)
}
export default SSG
npm run build 로 빌드를 실행하고, npm run dev 실행시 브라우저에서 http://localhost:3000/ssg에 접속하면 구현한 페이지가 표시됨을 확인할 수 있음.
getStaticProps라는 함수를 정의하고 익스포트하면, 해당 함수는 빌드 시 실행된다.getStaticProps는 반환값으로 props를 반환할 수 있으며, 그 값이 페이지 컴포넌트에 전달되어 그려진다.pages/ssg.tsx 에 getStaticProps를 추가하고, 다시 빌드해보자.import { GetStaticProps, NextPage, NextPageContext } from 'next' // 타입을 위해 도입
import Head from 'next/head' // Next.js의 내장 컴포넌트
// 페이지 컴포넌트의 props 타입 정의
type SSGProps = {
message: string;
}
// SSG는 getStaticProps가 반환한 props를 받을 수 있다.
// NextPage<SSGProps>는 Message: string만을 받아 생성된 페이지 타입
// Next.js의 페이지 컴포넌트나 함수 타입은 공식 문서 참고
const SSG: NextPage<SSGProps> = (props) => {
const { message } = props;
return (
<div>
{/* Head 컴포넌트로 감싸면, 그 요소는 <head> 태그에 배치됨 */}
<title>Static Site Generation</title>
<link rel="icon" href="/favicon.io" />
<main>
<p>이 페이지는 정적 사이트 생성을 통해 빌드 시 생성된 페이지입니다.</p>
<p>{message}</p>
</main>
</div>
);
};
// getStaticProps는 빌드 시 실행된다.
// GetStaticProps<SSGProps>는 SSGProps 인수로 받는 getStaticProps 타입
export const getStaticProps: GetStaticProps<SSGProps> = async (context) => {
const timestamp = new Date().toLocaleString();
const message = `${timestamp}에 getStaticProps가 실행됐습니다.`;
console.log(message);
return {
// 여기에서 반환된 props를 기반으로 페이지 컴포넌트를 그린다.
props: {
message,
},
};
};
export default SSG
npm run build를 실행하면 getStaticProps 안에 있는 console.log가 빌드 도중 실행되는 것을 확인할 수 있다.
npm run start 실행해서, 페이지를 표시하면 getStaticProps에서 반환한 props를 사용해 페이지를 표시하고 있는 것을 확인할 수 있다.
npm run dev 를 사용해 개발 서버를 실행하는 경우에는 최신 코드를 사용해 페이지를 표시하기 때문에, 요청이 있을 때마다 getStaticProps가 실행되고 서버에서 페이지를 생성
getStaticProps는 익스포트(export)해야 하며, 비동기 함수로서 async와 함께 정의해야함getStaticProps의 인수에는 context가 부여된다.context에는 빌드 시에 함께 사용할 수 있는 데이터가 포함되어 있다.export async function getStaticProps(context) {
return {
props: {}
}
}
context는 실행 관련 정보가 모인 객체로, context.locale과 같은 형태로 접근가능하다.| 파라미터 | 내용 |
|---|---|
| params | 경로 파라미터, SSG의 경우에는 getStaticPaths 함수를 별도로 정의했을 때 참조 가능 |
| locale | 현재 로케일 정보(가능한 경우) |
| locales | 지원하는 로케일 배열(가능하는 경우) |
| preview | Preview Mode 여부 |
| previewData | Preview Mode에서 setPreviewData에 따라 설정된 데이터 |
[파라미터].tsx 와 같이 [] 로 감싼 특별한 파일명getStaticProps에 맞춰 getStaticPaths를 사용한다.getStaticProps 실행 전에 호출되는 함수로, 생성할 페이지의 경로 파라미터 조합(paths)과 폴백(fallback)을 반환한다.paths는 경로 파라미터의 조합을 나타내며, 배열의 각 요소가 1개의 페이지에 대응한다.fallback은 getStaticPaths가 생성하는 페이지가 존재하지 않는 경우의 처리를 기술한다.export async function getStaticPaths() {
return {
paths: [
{ params: { ... } }
],
fallback: false // true 또는 'blocking' 지정 가능
}
}
pages/posts 디렉터리를 새롭게 만들고, [id].tsx(pages/posts/[id].tsx) 라는 파일을 만든다.import { GetStaticPaths, GetStaticProps, NextPage } from "next";
import Head from 'next/head';
import { useRouter } from "next/router";
import { ParsedUrlQuery } from "querystring";
type PostProps = {
id: string;
}
const Post: NextPage<PostProps> = (props) => {
const {id} = props
const router = useRouter()
if (router.isFallback) {
// 폴백 페이지용 표시를 반환한다.
return <div>Loading...</div>
}
return (
<div>
<Head>
<title>Create Next app</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<p>이 페이지는 정적 사이트 생성을 통해 빌드 시 생성된 페이지입니다.</p>
<p>{`/post/${id}에 대응하는 페이지입니다.`}</p>
</main>
</div>
)
}
// getStaticPaths는 생성한 페이지의 경로 파라미터 조합을 반환한다.
// 이 파일은 pages/posts/[id].tsx 이므로, 경로 파라미터로서 id의 값을 반환해야 한다.
export const getStaticPaths: GetStaticPaths = async () => {
const paths = [
{
params : {
id: '1',
},
},
{
params : {
id: '2',
},
},
{
params : {
id: '3',
},
},
]
// fallback을 false로 설정하면, paths에 정의된 페이지 외에는 404 페이지를 반환한다.
return {paths, fallback: false}
}
// 파라미터 타입을 정의
interface PostParams extends ParsedUrlQuery {
id: string
}
// getStaticPaths 실행 후에 각 경로에 대해 getStaticProps가 실행된다.
export const getStaticProps: GetStaticProps<PostProps, PostParams> = async (context) => {
return {
props: {
id: context.params!['id'],
}
}
}
export default Post
getStaticPaths 에서는 id가 각각 1, 2, 3 인 경로 파라미터를 반환하고 /posts/1, /posts/2, /posts/3의 3개 경로의 페이지를 생성한다.paths의 각 요소에 추가 파라미터를 더할 수 있다.paths의 각 요소에 대해 getStaticProps가 호출되고, 페이지가 생성된다.getStaticProps에는 context인 params로부터 경로 파라미터를 참조할 수 있다.getStaticPaths의 fallback을 false로 반환하면 paths에 주어지지 않은 경로에 대해서는 404 페이지를 표시한다.fallback에 true를 지정하면, 최초 요청과 그 뒤의 요청에서 작동이 달라진다.props가 빈 상태로 화면이 그려진 페이지이다.getStaticProps를 실행한다. getStaticProps가 반환한 props는 페이지를 표시하고 있는 클라이언트에 전송되고 화면을 그린다.
fallback: false 인 경우
fallback: true 인 경우
getStaticProps에 대해, SSR에서는 getServerSideProps를 정의한다.getServerSideProps 를 호출하며, 이 함수가 반환한 props 를 기반으로 페이지를 그린다.pages/ssr.tsx를 새롭게 작성하고, 다음 코드를 추가해보자.import { GetServerSideProps, NextPage } from "next";
import Head from 'next/head';
type SSRProps = {
message: string
}
const SSR: NextPage<SSRProps> = (props) => {
const {message} = props
return (
<div>
<Head>
<title>Create Next App</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<p>이 페이지는 서버 사이드 렌더링을 통해 접근 시에 서버에서 그려진 페이지 입니다.</p>
<p>{message}</p>
</main>
</div>
)
}
// getServerSideProps는 페이지로의 요청이 있을 때마다 실행된다.
export const getServerSideProps: GetServerSideProps<SSRProps> = async (
context
) => {
const timestamp = new Date().toLocaleDateString()
const message = `${timestamp}에 이 페이지의 getServerSideProps가 실행됐습니다.`
console.log(message)
return {
props: {
message,
}
}
}
export default SSR

getServerSideProps의 인수인 context 에는 getStaticProps의 context에서 참조할 수 있는 데이터와 함께 요청 정보들을 참조할 수 있다.| 파라미터 | 내용 |
|---|---|
| req | http.IncomingMessage의 인스턴스에서 요청 정보나 쿠키(Cookie)를 참조할 수 있다. |
| res | http.ServerResponse의 인스턴스에서 쿠키를 설정하거나, 응답 헤더를 치환할 때 사용할 수 있다. |
| resolveUrl | 실제로 접근이 있던 경로 |
| query | 해당 쿼리를 객체로 만든 것 |
revalidate를 반환하는 getStaticProps를 사용한다. getStaticProps에서 revalidate를 반환하면 그 값이 유효 기간이 되며, 유효 기간이 지난 페이지는 재생성된다.pages/isr.tsx)getStaticProps를 정의하고, getStaticProps에서는 props와 함께 revalidate를 반환한다.revalidate는 페이지의 유효 기간을 초로 나타낸 것을 반환한다.import { GetStaticPaths, NextPage, GetStaticProps } from "next";
import Head from 'next/head'
import {useRouter} from 'next/router'
type ISRProps = {
message: string
}
// ISRProps를 받는 NextPage(페이지) 타입
const ISR: NextPage<ISRProps> = (props) => {
const {message} = props
const router = useRouter()
if (router.isFallback) {
return <div>Loading...</div>
}
return (
<div>
<Head>
<title>Create Next App</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<p>이 페이지는 ISR을 통해 빌드 시 생성된 페이지입니다.</p>
<p>{message}</p>
</main>
</div>
)
}
export const getStaticProps: GetStaticProps<ISRProps> = async (context) => {
const timestamp = new Date
const message = `${timestamp}에 이 페이지의 getStaticProps가 실행됐습니다.`
return {
props : {
message,
},
// 페이지의 유효 기간을 초 단위로 지정
revalidate: 60
}
}
export default ISR
getStaticProps를 기반으로 클라이언트에서 다시 화면을 그린다.revalidate에서 지정한 시간 내에서는 서버 사이드에서 그려서 저장하고 있던 페이지(같은 페이지)를 반환한다.getStaticProps를 실행하고 페이지를 그려 새로운 캐시로 저장한다.