はじめに
Vite で作った React の ToDo アプリを GitHub Pages に公開したので、自分の整理用に手順をまとめました。gh-pages というパッケージを使って、コマンド1つで公開できるようにします。完成したページはこちらです。
※ パッケージとは、ほかの人が作って公開している便利なプログラムのまとまりのことです。npm install で自分のプロジェクトに追加して使えます(React や Vite もパッケージです)。
環境
- Node.js v24.11.0 / npm 11.6.1
- Vite 8 / React 19
- gh-pages 6.3.0
全体の流れ
やっていることは、大きく分けると 「作る → 変換する → 置く」 の3段階です。表の手順名をクリックすると、対応する本文の見出しに移動できます。「変換する」ではビルド時の設定を行い、実際のビルドは手順6でアップロードとまとめて実行します。
1. [作る] Vite で React プロジェクトを作る
GitHub Pages の URL や、あとで出てくる base の設定にはリポジトリ名を使います。なので、最初にリポジトリ名を決めておきましょう。ここでは react_todo_list にして、次のコマンドでプロジェクトを作ります。
npm create vite@latest react_todo_list
| 部分 | 意味 |
|---|---|
npm |
パッケージを管理するための道具。Node.js をインストールすると一緒に入る |
npm create vite@latest |
Vite が用意している「ひな形を作るツール」を、最新版(latest)で実行する。package.json・vite.config.js・index.html・src/ など、React アプリに必要なファイル一式を自動で作ってくれる |
react_todo_list |
作るフォルダ(プロジェクト)の名前。決めておいたリポジトリ名と同じにしている |
実行すると、どの種類のプロジェクトを作るかを選ぶ画面が出ます。矢印キーで選んで Enter を押します。今回は Select a framework:(使うフレームワーク)で React、Select a variant:(使う言語)で JavaScript を選びました。選択後、作ったフォルダに移動して、パッケージをインストールします。
cd react_todo_list
npm install
npm install は、package.json に書かれているパッケージ(React や Vite など)をインストールするコマンドです。インストールしたものは node_modules フォルダに入ります。パッケージの準備ができたら、次のコマンドで開発用サーバーを起動します。
npm run dev
ブラウザは JSX をそのまま読めませんが、開発用サーバーは JSX をブラウザが読める JS にその場で変換して見せてくれます。ファイルを保存するとすぐ画面に反映されるので、作りながら確認するときに使います(止めるときは Ctrl + C)。ターミナルに表示された URL(通常は http://localhost:5173/)をブラウザで開いて、Vite と React のロゴのページが出れば準備完了です。
2. [作る] GitHub に push して作業用ブランチで実装する
GitHub で、手順1で決めた名前(react_todo_list)のリポジトリを作ります。私の環境では、Git で新しくリポジトリを作るときの初期ブランチ名を main に設定しているため、この記事も main を前提に進めます。まず、Vite で作ったばかりの状態を main ブランチに push します。
git init
git add .
git commit -m "Initial commit (vite react template)"
git remote add origin https://github.com/<ユーザー名>/react_todo_list.git
git push -u origin main
このとき使った Git のオプション
| 記述 | 意味 |
|---|---|
git remote add origin <URL> |
リモートリポジトリ(GitHub 上のリポジトリ)の URL に origin という ニックネーム を付ける。一度付ければ git push origin main のように、長い URL の代わりに origin と書くだけで済む。名前は自由に決められるが、最初に登録するリモートには origin を使うのが一般的 |
git push -u origin main |
-u は --set-upstream の略で、ローカルの main とリモート(origin)の main を「対応するペア」として登録する。通常の設定では、登録後は main にいるとき、git push や git pull だけで済む |
このペアの登録は ブランチごと に行います。push するブランチを指定したいときは、git push origin <ブランチ名> のように書きます。新しいブランチを初めて push するときも -u を付けておくと、そのあとが楽になります。
作業用ブランチでアプリを実装する
次に、作業用のブランチ react-todo を作ります。アプリの実装やデプロイの設定はこのブランチで行います。初期状態の main と比べられるので、Pull Request で変更点がわかりやすくなります。
git switch -c react-todo
-c は create(作る)の略で、ブランチを 新しく作って、そのまま切り替える ところまで1回で行えます。react-todo ブランチで、ひな形の src/App.jsx を ToDo アプリに書き換えていきます。今回作ったアプリでできることは次のとおりです。
- タスクの追加(空欄や空白だけのときは追加しない)
- チェックボックスで完了・未完了の切り替え(完了したら取り消し線)
- 「編集」でその場で書き換え、「削除」で確認してから削除
- 全てのタスク・完了済み・未完了の件数の表示
App.jsx 1つに全部書くと読みにくくなるので、役割ごとにコンポーネント(画面の部品)を分けました。作っている途中は npm run dev を起動しておくと、保存するたびにブラウザに反映されるので、確認しながら進められます。
src/
├── App.jsx … 全体をまとめる。タスクの一覧(todos)を state で持つ
├── main.jsx … App を画面に表示する(ひな形のまま)
└── components/
├── TodoForm.jsx … 入力欄と「保存」ボタン
├── TodoCount.jsx … 件数の表示
├── TodoList.jsx … タスクの一覧
└── TodoItem.jsx … タスク1行分(チェック・編集・削除)
※ この記事の本題は GitHub Pages への公開なので、アプリのコードの説明は省略します。全体のコードは今回の Pull Requestで見られます。
実装できたらコミットして、react-todo ブランチを GitHub に push します。このブランチを初めて push するので、main のときと同じように -u を付けておきます。push したら、GitHub で main ← react-todo の Pull Request を作っておきます。
git add .
git commit -m "Implement ToDo list"
git push -u origin react-todo
GitHub Pages を無料プランで使う場合、リポジトリは Public にしておく必要があります。
3. [変換する] vite.config.js に base を設定する
ここがいちばん大事なポイントです。vite.config.js は Vite の設定ファイルで、npm run dev や npm run build を実行すると、Vite はこのファイルに書かれた設定に従って動きます。手順1のひな形に最初から入っています。
なぜ base が必要なのか
今回のように GitHub Pages のプロジェクトサイトとして公開すると、アプリの URL は https://<ユーザー名>.github.io/<リポジトリ名>/ になります。ところが Vite は、何も設定しないと JS や CSS のファイルを https://<ユーザー名>.github.io/assets/... のように、リポジトリ名を含まない場所から読み込もうとします。実際のファイルは /<リポジトリ名>/assets/... にあるので見つからず、ページが真っ白になる原因になります。
そこで、「このアプリは /<リポジトリ名>/ の場所に置かれる」と Vite に教えるのが base です。vite.config.js を開いて、base の1行を追加します。
// vite.config.js
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [react()],
base: '/react_todo_list/', // 公開先の /リポジトリ名/
})
| 記述 | 意味 |
|---|---|
defineConfig |
define(定義する)+ config(configuration=設定)で、「設定を定義する」という名前の関数。中に書いた設定をそのまま Vite に渡す |
plugins: [react()] |
React 向けの開発機能を提供するプラグインを使う設定。ひな形に最初から入っている |
base |
ファイルの読み込み先の基準となるパス。今回の公開先では /リポジトリ名/ にする |
今回の base の値は、公開したあとの URL から、ドメイン(https://<ユーザー名>.github.io)を取り除いた残りと覚えるとわかりやすいです。公開先の /react_todo_list/ に合わせて、JS や CSS の読み込み先が生成されます。
※ base を設定すると、npm run dev で開く URL も http://localhost:5173/react_todo_list/ に変わります。
4. [置く] gh-pages をインストールする
gh-pages は、指定したフォルダの中身を、GitHub の gh-pages という名前のブランチに push してくれるパッケージです。自分でブランチを作ってファイルをコピーして……という手間を、コマンド1つで済ませられます。
npm install -D gh-pages
-D(--save-dev の略)は、パッケージを 「開発のときに使うもの」 として登録するオプションです。package.json にはパッケージを登録する場所が2つあります。gh-pages は公開作業のときに使うだけで、ブラウザでアプリが動くときには必要ないので、devDependencies に入れています。
| 場所 | 入るもの | 例 |
|---|---|---|
dependencies |
アプリが動くために必要なもの |
react、react-dom
|
devDependencies |
作ったり公開したりするときに使うもの |
vite、gh-pages
|
5. [置く] package.json に deploy スクリプトを追加する
package.json は プロジェクトの設定表です。プロジェクトの名前、使っているパッケージ、よく使うコマンドなどが書かれていて、手順1のひな形に最初から入っています。この中の scripts には、「名前」と「実際に実行するコマンド」の組を登録できるので、既存の項目を残したまま deploy を追加します。
以下は scripts 部分の例です。preview の行の最後に , を付けるのを忘れずに、deploy の1行を追加します。自分のファイルに lint など別の項目がある場合は、その項目も残します。
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"deploy": "npm run build && gh-pages -d dist"
}
npm run ○○ と打つと、npm が scripts から ○○ という名前を探し、そこに書かれたコマンドを実行します。今回の設定では、それぞれ次のように対応しています。
| 打つコマンド | 実際に実行されるもの |
|---|---|
npm run dev |
vite(開発用サーバーを起動) |
npm run build |
vite build(公開用のファイルを作る) |
npm run preview |
vite preview(作ったファイルを手元で確認) |
npm run deploy |
npm run build && gh-pages -d dist |
※ deploy の中に npm run が出てくるので、「npm run npm run build になるの?」と思うかもしれません。そうはなりません。
npm run deploy は、登録された値である npm run build && gh-pages -d dist をコマンドとして実行します。
deploy の中身
| 部分 | 意味 |
|---|---|
npm run build |
scripts の build(vite build)を実行する。JSX や CSS などのファイルを変換・整理し、公開用のファイルを dist フォルダに出力する |
&& |
「前のコマンドが成功したら、次のコマンドを実行する」という意味。ビルドに失敗したときはアップロードされない |
gh-pages -d dist |
dist フォルダの中身を gh-pages ブランチに push する。-d は --dist の略で、「どのフォルダを公開するか」を指定するオプション |
※ dist は distribution(配布)の略で、完成品を配るためのフォルダです。中身は npm run build のたびに作り直されるので、自分で編集はしません。直すときは src のほうを直します。
公開する前に手元で見た目を確かめたいときは、npm run build のあとに npm run preview を実行します。表示された URL(通常は http://localhost:4173/react_todo_list/)を開くと、ビルドしたファイルの表示や動作を確認できます。
6. [置く] npm run deploy でビルドしてアップロードする
次のコマンドで公開用のファイルをビルドし、gh-pages ブランチにアップロードします。初回は、このあと手順7で GitHub Pages の公開元を設定します。
npm run deploy
※ ターミナルのプロンプト(% より左の部分)は自分で設定を変えているため、通常の表示とは少し違います。
※ git worktree を使って作業しているため、フォルダ名がリポジトリ名の react_todo_list ではなく、react_todo_list-react-todo になっています。
※ 青いかっこ [react-todo] の部分は、今いるブランチ名です。
※ % より右の npm run deploy が、今回実行したコマンドです。
途中の > vite build から ✓ built in 113ms までがビルド(変換)で、ログには出力されたファイルが表示されています。最後に Published と表示されれば、gh-pages によるアップロードは成功です。GitHub のリポジトリを見ると gh-pages ブランチが作られています。
このブランチにアップロードするのは、src のソースコードではなく、dist の中身である公開用のファイルです。スクリーンショットには .gitignore と .oxlintrc.json も写っていますが、これらは今回 dist からアップロードするファイルとは別のものです。
npm run deploy は、手元(いま開いているブランチ)のファイルをビルドしてアップロードします。そのため、main にマージする前でも、作業ブランチの react-todo のまま公開の準備を進められます。
7. [置く] GitHub Pages の公開元を設定する
最後に、GitHub に「どのブランチを Web サイトとして公開するか」を教えます。リポジトリページで、次のように設定します。
- Settings を開き、左のメニューから Pages を選ぶ
- Build and deployment の Source で「Deploy from a branch」を選ぶ
- Branch で「gh-pages」と「/ (root)」を選んで Save を押す
「gh-pages ブランチのいちばん上(root)にあるファイルを公開する」という意味です。数分待ってから https://<ユーザー名>.github.io/<リポジトリ名>/ を開き、アプリが表示されれば完了です。
更新するときとつまずきポイント
コードを直したら、もう一度 npm run deploy を実行すると、GitHub Pages 側の処理後に公開中のページへ反映されます。作業ブランチに push しただけでは、公開中のページは変わりません。今回の設定では、公開元が gh-pages ブランチだからです。
npm run deploy
| 症状 | 確認すること |
|---|---|
| ページが真っ白になる |
base の設定が公開先と合っているか確認する。ブラウザの開発者ツールで、JS や CSS が 404 エラーになっていないかも確認する |
| 404 ページが出る | Settings → Pages の Branch が gh-pages になっているか確認する。反映まで数分かかることもある |
| 直したのに反映されない |
npm run deploy を再実行し、GitHub Pages 側の処理完了を待つ。それでも変わらない場合は、ブラウザで強制再読み込み(Mac:Cmd + Shift + R)をする |
npm run dev で開いても表示されない |
base 設定後の URL を確認する。今回の設定では、通常は http://localhost:5173/react_todo_list/ になる |
感想:実際にやってみて理解が変わったこと
試しに base を外してビルドしてみたら、index.html に書かれる読み込み先から /react_todo_list/ が消えました。なぜ必要なのか最初はピンとこなかったけど、実際に変わるのを見て理解できました。
| 対象 | 学ぶ前 | 実際にやってみて |
|---|---|---|
base |
なぜ必要なのかピンとこなかった |
base を外してビルドすると、index.html の読み込み先から /react_todo_list/ が消えるのを確認して納得できた |
| Vite の役割 | ブラウザが読めるように JSX を JS に変換してくれるもの | 変換するだけでなく、App.jsx や各コンポーネント、CSS などのバラバラのファイルをまとめて(バンドルして)くれるとわかった。今回の出力では JS と CSS がそれぞれ1つにまとまり、base のパスが index.html の読み込み先に反映されていた |
npm run dev |
バイブコーディングのときにも打っていたが、中で何が動いているのかは気にしていなかった |
package.json を見て、scripts に登録された dev を実行しているだけだとわかった。以前のプロジェクトの package.json を見ると、中身は vite ではなく next dev(Next.js)だった |
同じコマンドでも、プロジェクトによって中で動くツールは違うんだなと気づけました。npm run dev の中身を見たいときは、package.json の scripts を見て確認しようと思います。
まとめ
-
vite.config.jsにbase: '/リポジトリ名/'を書く -
gh-pagesを入れ、package.jsonのscriptsにdeploy(npm run build && gh-pages -d dist)を追加する -
npm run deployでビルドしたファイルをgh-pagesブランチにアップロードする - GitHub の Settings → Pages で、公開元を
gh-pagesブランチにする
特に base の設定は、忘れるとページが真っ白になるので、公開前に確認しておきたいポイントです。


