Next.js GitHub Pages 정적 배포하기
Next.js 프로젝트를 GitHub Pages에 정적 배포하는 방법에 대해 정리한 페이지입니다.
Tags
CI, CD, GitHub, GitHub Actions, GitHub Pages, Next.js, Static Export, YML
Environment
Next.js v16.1.4
1. 개요
Next.js 프로젝트를 GitHub Pages에 정적 배포하는 방법에 대해 정리한 페이지입니다. 이번 글에서는 Next.js로 만든 MDX 블로그를 GitHub Pages에 정적 배포하는 방법에 대해 설명합니다.
2. GitHub Actions
이번 글에서는 GitHub Pages에 배포하기 GitHub Actions를 활용합니다.
GitHub Actions로 CI/CD 구축 방법에 대한 글을 참고하시는 것을 추천드립니다.
3. Step 1 - generateStaticParams 설정하기

먼저 Next.js 프로젝트를 정적 배포하기 위해선 모든 동적 라우트를 SSG로 변경해야 합니다.
npm run build 명령어를 실행하여 빌드한 결과물을 보면 위의 사진과 같이 서버에서 on-demand로 렌더링되는 페이지가 있음을 확인할 수 있습니다.
동적 라우트를 SSG로 변경하기 위해선 generateStaticParams 함수를 통해 빌드 시점에 모든 라우트를 정의하면 됩니다.
다음과 같이 generateStaticParams를 설정하고 다시 빌드하면, 모든 페이지가 정적으로 생성되는 것을 확인할 수 있습니다.
1/* @/app/categories/[category]/page.tsx */
2
3import { getCategoryList, getPostListByCategory } from "@/entities/post";
4import { convertDateFormat } from "@/shared/lib/utils";
5import Link from "next/link";
6import { FaFolderOpen } from "@react-icons/all-files/fa/FaFolderOpen";
7
8export async function generateMetadata({
9 params,
10}: {
11 params: Promise<{ category: string }>;
12}) {
13 const { category } = await params;
14 const decodedCategory = decodeURIComponent(category);
15
16 return {
17 title: decodedCategory,
18 description: `${category} 페이지`,
19 };
20}
21
22export default async function Page({
23 params,
24}: {
25 params: Promise<{ category: string }>;
26}) {
27 const { category } = await params;
28 const decodedCategory = decodeURIComponent(category);
29 const postList = await getPostListByCategory(decodedCategory);
30
31 return (
32 <main className="flex w-full flex-col gap-8 dark:bg-black">
33 <h1 className="flex flex-row items-baseline gap-2 text-[2rem] font-bold">
34 <FaFolderOpen className="text-custom-gray text-2xl" />
35 {decodedCategory}
36 <span className="text-custom-gray pl-2 text-xl font-light">
37 {postList.length}
38 </span>
39 </h1>
40 <ul className="marker:text-custom-gray list-disc pl-4">
41 {postList.map((post) => (
42 <li key={post.postPath}>
43 <div className="flex flex-row items-center gap-2 py-2 pr-4">
44 <Link
45 className="text-custom-blue text-lg underline-offset-4 hover:text-teal-500 hover:underline dark:text-blue-300"
46 href={`/posts/${post.postPath}`}
47 >
48 {post.title}
49 </Link>
50 <span className="flex-1 border border-dashed border-gray-300" />
51 <time className="text-custom-gray">
52 {convertDateFormat(post.date)}
53 </time>
54 </div>
55 </li>
56 ))}
57 </ul>
58 </main>
59 );
60}
61
62export async function generateStaticParams() {
63 const categoryList = await getCategoryList();
64
65 return categoryList.map((category) => ({
66 category: category.title,
67 }));
68}
69
70export const dynamicParams = false;
4. Step 2 - GitHub Pages 설정하기
GitHub Pages로 배포하기 위해선 먼저 정적 배포하고자 하는 Repository에서 Settings > Pages로 이동한 후
Build and deployment의 source를 GitHub Actions로 지정합니다.


5. Step 3 - next.config.ts 설정하기
next.config.ts 파일에서 output: "export"를 설정함으로써 정적 HTML, CSS, JavaScript만 포함하는 out 폴더 결과물을 내보낼 수 있습니다.
또한 GitHub Pages는 HyunJinNo.github.io/<Repository 이름> URL을 사용하므로 basePath로 Repository 이름을 설정합니다.
또한 SSG 환경에서는 서버 기능이 필요한 이미지 최적화 기능을 사용할 수 없으므로 이미지 최적화 기능을 비활성화합니다.
1/* next.config.ts */
2
3const nextConfig: NextConfig = {
4 /* config options here */
5 output: "export",
6 basePath: "/mdx-blog",
7 images: {
8 unoptimized: true,
9 },
10
11 /* ... */
12};Caution
basePath를 설정하기 않는 경우, 다음과 같이 css 파일이나 이미지 경로에서 오류가 발생합니다.
6. Step 4 - Workflow 작성하기
1# workflow 이름 설정
2name: Deploy Next.js site to Pages
3
4# workflow를 트리거하는 이벤트 설정
5on:
6 push:
7 branches: ["main"]
8
9# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
10permissions:
11 contents: read
12 pages: write
13 id-token: write
14
15# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
16# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
17concurrency:
18 group: "pages"
19 cancel-in-progress: false
20
21# 실행할 jobs 설정
22jobs:
23 # Build job
24 build:
25 # Ubuntu 환경에서 실행
26 runs-on: ubuntu-latest
27
28 steps:
29 - name: Checkout code
30 uses: actions/checkout@v6
31
32 - name: Install Node.js
33 uses: actions/setup-node@v6
34 with:
35 # Node.js 버전 설정
36 node-version: 24
37
38 - name: Install dependencies
39 run: npm install
40
41 - name: Setup Pages
42 id: setup_pages
43 uses: actions/configure-pages@v5
44
45 - name: Build with Next.js
46 run: npm run build
47
48 - name: Upload artifact
49 uses: actions/upload-pages-artifact@v4
50 with:
51 path: ./out
52
53 # Deployment job
54 deploy:
55 needs: build
56 environment:
57 name: github-pages
58 url: ${{ steps.deployment.outputs.page_url }}
59 runs-on: ubuntu-latest
60 steps:
61 - name: Deploy to GitHub Pages
62 id: deployment
63 uses: actions/deploy-pages@v4위의 workflow 설정에 대해 설명하자면 다음과 같습니다.
6.1. workflow 이름 설정하기
1# workflow 이름 설정
2name: Deploy Next.js site to Pages먼저 위와 같이 workflow 이름을 설정해야 합니다. workflow 이름은 name 필드에서 설정합니다. 이 이름은 GitHub의 Actions 탭에 표시됩니다.

6.2. 이벤트 설정하기
1# workflow를 트리거하는 이벤트 설정
2on:
3 push:
4 branches: ["main"]on 필드에서는 workflow를 트리거하는 이벤트를 정의합니다.
가장 많이 사용하는 이벤트로는 push, pull_request 등이 있습니다.
위의 예시는 main 브랜치에 코드 푸시가 이루어질 때 workflow를 트리거합니다.
6.3. GITHUB_TOKEN 권한 설정하기
1# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
2permissions:
3 contents: read
4 pages: write
5 id-token: write위와 같이 GITHUB_TOKEN 권한을 설정해야 합니다. 권한 설정을 해야 GitHub Pages에 배포할 수 있습니다.
| 권한 | 이유 |
|---|---|
| contents: read | repository 코드 읽기 |
| pages: write | Pages 배포 |
| id-token: write | OIDC 인증용 |
6.4. concurrency 설정하기
1# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
2# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
3concurrency:
4 group: "pages"
5 cancel-in-progress: false동시에 여러 배포가 실행되지 않도록 방지하는 부분으로, 이전 배포는 취소하지 않습니다.
6.5. Job 설정하기
1# 실행할 jobs 설정
2jobs:
3 # Build job
4 build:
5 # Ubuntu 환경에서 실행
6 runs-on: ubuntu-latest
7
8 steps:
9 - name: Checkout code
10 uses: actions/checkout@v6
11
12 - name: Install Node.js
13 uses: actions/setup-node@v6
14 with:
15 # Node.js 버전 설정
16 node-version: 24
17
18 - name: Install dependencies
19 run: npm install
20
21 - name: Setup Pages
22 id: setup_pages
23 uses: actions/configure-pages@v5
24
25 - name: Build with Next.js
26 run: npm run build
27
28 - name: Upload artifact
29 uses: actions/upload-pages-artifact@v4
30 with:
31 path: ./out
32
33 # Deployment job
34 deploy:
35 needs: build
36 environment:
37 name: github-pages
38 url: ${{ steps.deployment.outputs.page_url }}
39 runs-on: ubuntu-latest
40 steps:
41 - name: Deploy to GitHub Pages
42 id: deployment
43 uses: actions/deploy-pages@v4jobs 필드는 workflow 내에서 실행될 개별 작업을 정의합니다. 각 job은 여러 단계를 포함할 수 있으며 병렬로 실행이 가능합니다.
먼저 다음과 같이 정의할 job의 이름을 설정해야 합니다. 이름은 자유롭게 지을 수 있습니다.
저의 경우에는 빌드를 수행하는 job인 build와 배포를 수행하는 job인 deploy를 정의하였고
build 이후 deploy를 수행하도록 설정하였습니다.
1# 실행할 jobs 설정
2jobs:
3 # Build job
4 build:
5 runs-on: ubuntu-latest
6
7 # ...
8
9 # Deployment job
10 deploy:
11 needs: build
12 environment:
13 name: github-pages
14 url: ${{ steps.deployment.outputs.page_url }}
15 runs-on: ubuntu-latest
16 steps:
17 - name: Deploy to GitHub Pages
18 id: deployment
19 uses: actions/deploy-pages@v4Info.
needs: build는 해당 job이 수행되기 위해 먼저 완료되어야 하는 job을 지정하는 부분입니다. 즉, build가 완료된 이후에 deploy를 수행합니다.
다음으로 해당 job이 실행될 환경을 지정합니다.
GitHub에서 제공하는 기본 runs-on는 ubuntu-latest, macos-latest, windows-latest 등이 있습니다.
1# Ubuntu 환경에서 실행
2runs-on: ubuntu-lateststeps 필드에는 job 내부에서 순차적으로 실행되는 개별 작업을 정의합니다.
Shell 명령어를 실행하거나, GitHub에서 제공하는 액션(Action)을 사용하여 설정할 수 있습니다.
저는 Next.js로 만든 MDX 블로그를 GitHub Pages에 정적 배포하는 작업을 정의해보도록 하겠습니다. 배포 과정은 다음과 같이 정의하였습니다.
- GitHub Repositoryd에 push된 코드 가져오기
- Node.js 설치하기
- 의존성 설치하기
- GitHub Pages 배포 환경 초기화하기
- Next.js 애플리케이션 빌드하기
- 정적 파일 업로드하기
- GitHub Pages에 정적 배포하기
6.5.1. GitHub Repository에 push된 코드 가져오기
먼저 GitHub Repository에 있는 코드를 가져와야 합니다. GitHub에서 제공하는 액션으로 actions/checkout이 있으며, 해당 액션을 사용해서 Repository의 코드를 가져올 수 있습니다.
1steps:
2 - name: Checkout code
3 uses: actions/checkout@v6name 필드는 각 단계의 이름을 지정하는 부분으로, job 실행 시 로그에 표시됩니다.
이름은 해당 단계가 하고자 하는 작업을 이해할 수 있게 작성하면 됩니다.
uses 필드는 GitHub에서 제공하는 액션 또는 서드파티 액션을 사용할 때 지정합니다.
예를 들어, actions/checkout@v6는
Code Repository를 체크아웃(=코드 가져오기)하는 액션입니다.
6.5.2. Node.js 설치하기
코드를 가져온 후에는 애플리케이션을 빌드할 수 있도록 Node.js를 설치해야 합니다.
GitHub에서는 다음과 같이 Node.js를 설치할 수 있는 액션을
제공합니다. 이 때, 특정 액션에 추가 인수를 전달할 때 사용하는 with 필드를 사용하여 설치하고자 하는 Node.js 버전을 지정해야 합니다.
1- name: Install Node.js
2 uses: actions/setup-node@v6
3 with:
4 # Node.js 버전 설정
5 node-version: 246.5.3. 의존성 설치하기
애플리케이션을 빌드하기 위해 npm install 명령어를 실행하여 의존성을 설치합니다.
package.json 기반으로 node_modules 설치합니다.
여기서 사용한 run은 셸 명령어를 실행할 때 사용합니다. 이 명령어는 정의된 환경에서 실행됩니다.
1- name: Install dependencies
2 run: npm install6.5.4. GitHub Pages 배포 환경 초기화하기
1- name: Setup Pages
2 id: setup_pages
3 uses: actions/configure-pages@v5애플리케이션 빌드 전, GitHub Pages 배포 환경을 초기화합니다.
6.5.5. Next.js 애플리케이션 빌드하기
1- name: Build with Next.js
2 run: npm run buildnpm run build 명령어를 실행하여 Next.js 애플리케이션을 빌드합니다.
6.5.6. 정적 파일 업로드하기
1- name: Upload artifact
2 uses: actions/upload-pages-artifact@v4
3 with:
4 path: ./out./out 폴더를 GitHub Pages 서버로 업로드합니다.
6.5.7. GitHub Pages에 정적 배포하기
1# Deployment job
2deploy:
3 needs: build
4 environment:
5 name: github-pages
6 url: ${{ steps.deployment.outputs.page_url }}
7 runs-on: ubuntu-latest
8 steps:
9 - name: Deploy to GitHub Pages
10 id: deployment
11 uses: actions/deploy-pages@v4마지막으로 빌드된 결과물을 GitHub Pages에 정적 배포합니다.
여기서 environment 부분은 GitHub UI에 배포 URL 표시하는 부분입니다.
7. Step 5 - GitHub Pages 정적 배포 결과
GitHub Pages 정적 배포 결과는 다음과 같습니다.

8. 참고 자료
- Release: GitHub Pages 정적 배포 by HyunJinNo · Pull Request #27 · HyunJinNo/mdx-blog
- Getting Started: Deploying | Next.js
- nextjs/deploy-github-pages: Next.js template to deploy to GitHub Pages as a static site.
- Guides: Static Exports | Next.js
- Next.js 프로젝트를 정적 페이지로 배포하기 (Github pages) | Corinthionia
- Next.js 프로젝트를 GitHub pages에 배포하기
- GitHub Pages 문서 - GitHub 문서

