はい、承知いたしました。ReactアプリケーションをGitHub Pagesにデプロイする簡単な手順について、約5000語の詳細な説明を含む記事を作成します。
React アプリケーションを GitHub Pages にデプロイする簡単ガイド:詳細解説付き
はじめに:あなたのReactアプリを世界に公開しよう!
あなたが素晴らしいReactアプリケーションを開発したとしましょう。ローカル環境では完璧に動作し、ユーザーインターフェースは洗練され、機能も意図通りに実装されています。しかし、本当にこのアプリケーションの価値を発揮するためには、それをインターネット上に公開し、誰でもアクセスできるようにする必要があります。ウェブサイトやアプリケーションをホスティングする方法は数多くありますが、静的なウェブサイト、特にフロントエンドだけで完結するシングルページアプリケーション(SPA)を公開する場合、GitHub Pagesは非常に魅力的で手軽な選択肢となります。
GitHub Pagesは、GitHubリポジトリから直接、静的なウェブサイトをホスティングできる無料のサービスです。セットアップは比較的簡単で、特にGitHubを既に利用している開発者にとっては、追加のツールやサービスを導入することなく、プロジェクトのコードと同じ場所でホスティングを管理できるという大きなメリットがあります。
Reactアプリケーションは、ビルドプロセスを経て最終的にHTML、CSS、JavaScriptといった静的なファイル群として出力されます。これはまさにGitHub Pagesが得意とする静的サイトの形式です。したがって、ReactアプリをGitHub Pagesにデプロイすることは、技術的に非常に理にかなった方法と言えます。
この記事では、ReactアプリケーションをGitHub Pagesにデプロイするためのステップを、初心者の方でも理解できるように詳細かつ丁寧に解説します。特に、最も一般的で簡単な方法である gh-pages
というnpmパッケージを利用した手法に焦点を当てて説明を進めます。単にコマンドを羅列するだけでなく、「なぜこの設定が必要なのか?」「このコマンドは何をしているのか?」といった背景知識や理由についても深く掘り下げて解説します。
また、ReactのようなSPAを静的ホスティングサービスであるGitHub Pagesにデプロイする際に発生しがちな「ルーティングの問題」についても詳しく説明し、その解決策を複数提示します。トラブルシューティングのセクションも設けており、もしデプロイがうまくいかなかった場合の対処法も網羅しています。
この記事を読み終える頃には、あなたは自分で開発したReactアプリケーションをGitHub Pagesにデプロイし、そのURLを友人や同僚に共有できるようになっているはずです。さあ、あなたのReactアプリを世界に解き放ちましょう!
対象読者
- Reactアプリケーションを開発した経験がある方。
- GitHubを使った基本的なバージョン管理ができる方。
- コマンドライン(ターミナル)の基本的な操作ができる方。
- Reactアプリを簡単に公開したいと考えている方。
必要なもの
- Node.jsとnpmまたはYarnがインストールされている環境。
- Gitがインストールされている環境。
- GitHubアカウント。
- デプロイしたいReactアプリケーションのプロジェクト(新規作成でも既存でも可)。
GitHub Pages とは? 静的サイトホスティングの頼れる味方
GitHub Pagesは、GitHubが提供する無料の静的サイトホスティングサービスです。あなたのGitHubリポジトリにHTML、CSS、JavaScriptなどの静的ファイルを置くだけで、簡単にウェブサイトとして公開できます。ブログ、ドキュメントサイト、ポートフォリオ、そして今回扱うReactのようなフレームワークでビルドされた静的SPAなど、様々な用途に利用されています。
GitHub Pagesには主に2つのタイプがあります。
-
ユーザー/オーガニゼーションサイト:
- ユーザーまたはオーガニゼーション(組織)ごとに一つだけ作成できます。
- リポジトリ名は
<username>.github.io
または<organization>.github.io
という特定の形式である必要があります。 - このリポジトリの
main
ブランチ(または他の指定したブランチ)のルートディレクトリにあるファイルがサイトとして公開されます。 - URLはリポジトリ名そのまま、
https://<username>.github.io/
となります。 - 通常、個人のポートフォリオサイトやブログなどに利用されます。
-
プロジェクトサイト:
- ユーザーまたはオーガニゼーションが所有する、上記以外の任意のリポジトリに対して作成できます。
- リポジトリの設定でGitHub Pagesを有効化し、どのブランチのどのディレクトリを公開するかを指定します。一般的には、
main
ブランチのdocs
フォルダ、または後述するデプロイツールが自動的に作成するgh-pages
ブランチのルートディレクトリを使用します。 - URLは
https://<username>.github.io/<repository-name>/
という形式になります。 - 特定のプロジェクトのドキュメントサイトや、今回のようにアプリケーションのデモサイトなどに利用されます。
Reactアプリケーションをデプロイする場合、通常はプロジェクトサイトとして公開することになります。したがって、デプロイされたサイトのURLはあなたのGitHubユーザー名とリポジトリ名に基づいて https://<username>.github.io/<repository-name>/
のような形になります。このURL形式が、後述するReactアプリの設定において非常に重要になります。
GitHub Pagesの利点は以下の通りです。
- 無料: 基本的な使用は無料です。
- 手軽さ: GitHubリポジトリと連携しているため、セットアップが簡単です。
- バージョン管理との連携: コードの変更がそのままサイトの更新に繋がりやすく、Gitによるバージョン管理の恩恵を受けられます。
- カスタムドメイン: 必要であれば、独自のドメインを設定することも可能です(追加費用は不要ですが、ドメイン登録自体には費用がかかります)。
一方で、制限事項もあります。
- 静的サイトのみ: サーバーサイドの処理(Node.jsのバックエンドAPIなど)をGitHub Pages上で実行することはできません。あくまで静的なファイルを提供するサービスです。
- ビルド処理はローカルまたはCI/CD: GitHub Pages自体がアプリケーションをビルドしてくれるわけではありません。ビルド済みの静的ファイルをプッシュする必要があります。
- 利用制限: ソフト制限として、1GBのソース容量、月間100GBの帯域幅、1時間あたり10回のビルドという上限があります。一般的な用途であれば問題になることは少ないでしょう。
Reactアプリケーションはクライアントサイドで実行されるため、ビルドして生成された静的ファイル群はGitHub Pagesで問題なくホストできます。これが、GitHub PagesがReactアプリのデプロイ先として人気がある理由です。
React アプリケーションとは? ビルドとSPAの性質
Reactは、ユーザーインターフェースを構築するためのJavaScriptライブラリです。コンポーネント指向で宣言的なUI開発を可能にし、モダンなウェブアプリケーション開発において広く採用されています。
Reactアプリケーション開発では、通常JSX(JavaScript XML)というJavaScriptの拡張構文を使ってコンポーネントを記述し、ES6+の新しいJavaScript機能やCSSプリプロセッサなどを利用します。これらのコードは、そのままではブラウザで直接実行できません。ブラウザが理解できる標準的なHTML、CSS、JavaScriptの形に変換する「ビルドプロセス」が必要です。
このビルドプロセスは、WebpackやParcel、Rollupといったモジュールバンドラーと、Babelのようなトランスパイラによって行われます。開発中は開発サーバーがこの変換をリアルタイムで行いますが、本番環境向けにデプロイする際には、これらのツールを使ってコードを最適化し、単一または複数のバンドルファイル(bundle.js
のようなファイル)や、CSSファイル、画像ファイルなどを生成します。これらの生成されたファイル群が、ウェブサーバー(今回の場合はGitHub Pages)によって提供される静的なコンテンツとなります。
Create React App (CRA) や Vite のようなReact開発ツールは、この複雑なビルド設定を抽象化してくれます。例えば、CRAの場合、npm run build
というコマンドを実行するだけで、プロジェクトのルートディレクトリに build
という名前のフォルダが生成され、その中に本番環境向けの最適化された静的ファイル一式が出力されます。Viteの場合は、デフォルトで dist
というフォルダにファイルが出力されます。
Reactアプリケーションのもう一つの重要な特性は、シングルページアプリケーション(SPA)であることが多い点です。SPAは、最初のページロード時に必要なHTML、CSS、JavaScriptのすべて(または大部分)を読み込み、その後の画面遷移はページのフルリロードなしにJavaScriptが動的にコンテンツを書き換えることで実現します。これにより、ネイティブアプリケーションのようなスムーズなユーザー体験を提供できます。
SPAにおける画面遷移は、React Routerなどのライブラリを使って「クライアントサイドルーティング」によって管理されます。これは、ブラウザの履歴API(History API)を利用してURLを変更しつつ、実際にはサーバーへの新しいリクエストは行わず、クライアントサイドのJavaScriptがそのURLに対応するコンポーネントをレンダリングする仕組みです。
このクライアントサイドルーティングの仕組みが、静的ホスティングサービスであるGitHub Pagesにデプロイする際に問題を引き起こすことがあります。GitHub Pagesは、リクエストされたURLに対応するファイルを探そうとします。もしユーザーがサイトのルートURL (https://<username>.github.io/<repository-name>/
) にアクセスした場合、GitHub Pagesは <repository-name>/index.html
ファイルを見つけてそれを返します。ブラウザは index.html
を読み込み、ReactアプリケーションのJavaScriptを実行します。そのJavaScriptがクライアントサイドルーターを起動し、アプリケーションが正常に表示されます。
しかし、もしユーザーがアプリケーション内の特定のパス、例えば https://<username>.github.io/<repository-name>/about
に直接アクセスした場合、GitHub Pagesは <repository-name>/about/index.html
や <repository-name>/about.html
というファイルを探そうとします。SPAでは通常、このようなパスに対応する物理的なHTMLファイルは存在しません。結果として、GitHub Pagesはリクエストされたファイルが見つからないため、標準の404 Not Foundエラーページを返してしまいます。これが、SPAを静的ホスティングする際に発生するルーティングの問題です。
この問題に対する対策については後ほど詳しく説明しますが、まずはこのビルドプロセスとSPAの性質、そしてGitHub Pagesとの相性を理解しておくことが重要です。
デプロイの準備:環境とプロジェクトのセットアップ
ReactアプリをGitHub Pagesにデプロイする前に、いくつかの準備が必要です。
1. Reactプロジェクトの準備
デプロイしたいReactアプリケーションのプロジェクトが必要です。まだプロジェクトがない場合は、新しく作成しましょう。最も一般的なのはCreate React App (CRA) または Vite を使用する方法です。
Create React App (CRA) で新規プロジェクトを作成する場合:
bash
npx create-react-app my-react-app
cd my-react-app
npm start # または yarn start
またはYarnを使用する場合:
bash
yarn create react-app my-react-app
cd my-react-app
yarn start
これにより、my-react-app
という名前の新しいReactプロジェクトが作成されます。
Vite で新規プロジェクトを作成する場合:
Viteは、CRAよりも高速な開発サーバーとビルドプロセスを提供するため、近年人気が高まっています。
bash
npm create vite@latest my-vite-app --template react
cd my-vite-app
npm install # または yarn install
npm run dev # または yarn dev
これにより、my-vite-app
という名前の新しいReactプロジェクトが作成されます。プロジェクト作成時のテンプレート選択でReactを選択します。
既存のReactプロジェクトを使用する場合:
既に開発中のプロジェクトがある場合は、そのプロジェクトフォルダに移動してください。デプロイ前に、ローカル環境で npm start
(CRA) または npm run dev
(Vite) でアプリケーションが正しく動作することを確認しておきましょう。また、本番ビルドがエラーなく成功するかを確認するために、一度 npm run build
(または yarn build
) を実行してみることをお勧めします。
ビルドコマンドが成功すると、CRAの場合は build
ディレクトリが、Viteの場合は dist
ディレクトリがプロジェクトのルートに生成されるはずです。これがデプロイされる静的ファイル群です。
2. GitとGitHubアカウントの準備
- Gitのインストール: Gitがまだインストールされていない場合は、公式ウェブサイトからダウンロードしてインストールしてください。
https://git-scm.com/downloads - GitHubアカウント: GitHubアカウントが必要です。まだ持っていない場合は、GitHubのウェブサイトで作成してください。
https://github.com/
3. GitHubリポジトリの作成
GitHubアカウントにログインし、デプロイしたいReactプロジェクト用の新しいリポジトリを作成します。
- GitHubのトップページ右上にある “+” アイコンをクリックし、「New repository」を選択します。
- リポジトリ名を入力します。例えば、CRAで作成したプロジェクト名と同じ
my-react-app
など、プロジェクトの内容が分かりやすい名前にするのが良いでしょう。このリポジトリ名が、デプロイ後のURLの一部 (https://<username>.github.io/<repository-name>/
) になります。 - 公開設定を選択します。GitHub PagesはPublicリポジトリであれば無料で利用できます。Privateリポジトリの場合、GitHub FreeプランではGitHub Pagesは利用できませんが、GitHub ProやTeamなどの有料プランでは利用可能です。今回は無料のPublicリポジトリで進めることを前提とします。
- READMEファイル、.gitignore、ライセンスなどは、必要に応じて追加してください。Reactプロジェクトを新規作成した場合は、既に
.gitignore
などが生成されているため、ここでは追加しなくても構いません。 - 「Create repository」ボタンをクリックしてリポジトリを作成します。
4. ローカルプロジェクトとGitHubリポジトリの連携
作成したGitHubリポジトリに、ローカルのReactプロジェクトのコードをプッシュします。
- ローカルのプロジェクトフォルダ(例:
my-react-app
)をターミナルで開きます。 - まだGitリポジトリになっていない場合は、初期化します。既存プロジェクトの場合はスキップしてください。
bash
git init - すべてのファイル(ただし
.gitignore
で指定されたファイルは除く)をステージングエリアに追加します。
bash
git add . - 変更をコミットします。
bash
git commit -m "Initial commit" - ローカルリポジトリを、GitHubで作成したリモートリポジトリに関連付けます。GitHubでリポジトリを作成した際に表示される「…or push an existing repository from the command line」セクションに記載されているコマンドを使用するのが最も確実です。通常は以下のようになります。(
<YOUR_USERNAME>
と<YOUR_REPOSITORY_NAME>
はご自身のものに置き換えてください)
bash
git remote add origin https://github.com/<YOUR_USERNAME>/<YOUR_REPOSITORY_NAME>.git
git branch -M main # メインブランチ名をmainに設定(masterの場合もある) - ローカルのコードをリモートリポジトリにプッシュします。
bash
git push -u origin main
これで、あなたのReactプロジェクトのコードがGitHubリポジトリにアップロードされました。GitHubのウェブサイトでリポジトリページを開き、ファイルが正しく表示されていることを確認してください。
デプロイツールの選択:gh-pages
の導入
ReactアプリケーションをGitHub Pagesにデプロイする方法はいくつかありますが、最も手軽で広く使われているのは gh-pages
というnpmパッケージを利用する方法です。
gh-pages
パッケージ: このパッケージは、プロジェクトのビルドディレクトリの内容を自動的にgh-pages
という名前のブランチにプッシュしてくれます。GitHub Pagesは通常、このgh-pages
ブランチ(またはmain
ブランチのdocs
ディレクトリなど)を認識してサイトとして公開する設定が可能です。gh-pages
を使うと、ビルド、新しいブランチの作成、ファイルのコピー、コミット、プッシュといった一連の手順をコマンド一つで実行できるようになり、非常に便利です。- GitHub Actions: より高度な自動化を目指す場合は、GitHub Actionsを使うことも可能です。これは、コードが特定ブランチにプッシュされた際などに、ビルドやデプロイといったワークフローを自動実行できるCI/CD(継続的インテグレーション/継続的デリバリー)サービスです。
gh-pages
パッケージと組み合わせたり、直接ビルドファイルをプッシュしたりするActionsワークフローを作成できます。CI/CDの導入はデプロイ作業を効率化しますが、設定ファイルの記述などgh-pages
単体よりは少し複雑になります。 - 手動デプロイ: ビルドしたファイルを自分で
gh-pages
ブランチにコピー&ペーストし、コミットしてプッシュするという手動の方法も原理的には可能ですが、手間がかかり非効率的です。
この記事では、手軽さを重視し、gh-pages
パッケージを使用した方法を詳細に解説します。
gh-pages
パッケージを使用したデプロイ手順:ステップバイステップ
いよいよ gh-pages
パッケージを使ったデプロイ手順に入ります。以下のステップに沿って作業を進めていきましょう。
ステップ1: gh-pages
パッケージのインストール
まずは、gh-pages
パッケージを開発依存としてプロジェクトにインストールします。
プロジェクトのルートディレクトリをターミナルで開き、以下のコマンドを実行します。
npmを使用する場合:
bash
npm install --save-dev gh-pages
Yarnを使用する場合:
bash
yarn add --dev gh-pages
--save-dev
オプション(または yarn add --dev
)は、このパッケージが開発時にのみ必要であることを示します。インストールが完了すると、プロジェクトの package.json
ファイルの devDependencies
セクションに gh-pages
が追加されていることを確認できます。
json
// package.json の一部
{
"name": "my-react-app",
"version": "0.1.0",
// ... other properties
"devDependencies": {
// ... other dev dependencies
"gh-pages": "^5.0.0" // バージョンは異なる場合があります
},
"dependencies": {
// ... dependencies
}
// ... rest of package.json
}
ステップ2: package.json
の設定変更
gh-pages
パッケージを利用してReactアプリを正しくデプロイするために、package.json
ファイルにいくつかの設定を追加・変更する必要があります。
a. homepage
プロパティの追加
プロジェクトのルートURLをGitHub PagesのURLに設定するために、package.json
に homepage
プロパティを追加します。この設定は、特にReactアプリケーションのビルドプロセスにおいて、CSSやJavaScriptなどのバンドルファイルへの参照パスを正しく解決するために非常に重要です。
GitHub PagesのプロジェクトサイトのURLは https://<username>.github.io/<repository-name>/
という形式になります。したがって、homepage
の値もこの形式で指定します。
package.json
ファイルを開き、既存のプロパティ(例: name
, version
, dependencies
など)と同じ階層に homepage
プロパティを追加してください。
json
// package.json
{
"name": "my-react-app",
"version": "0.1.0",
"homepage": "https://<YOUR_USERNAME>.github.io/<YOUR_REPOSITORY_NAME>", // ★ この行を追加 ★
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
// ... other dependencies
},
"devDependencies": {
// ... other dev dependencies
"gh-pages": "^5.0.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
// ... rest of scripts
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
<YOUR_USERNAME>
の部分はあなたのGitHubユーザー名に、<YOUR_REPOSITORY_NAME>
の部分はGitHubで作成したリポジトリ名にそれぞれ置き換えてください。
なぜこの設定が必要なのか?
Reactアプリケーションのビルドプロセスでは、生成されるHTMLファイル (index.html
) からJavaScriptやCSSなどのバンドルファイルを参照するための <script>
や <link>
タグが埋め込まれます。デフォルトの設定では、これらの参照パスは /static/js/bundle.js
のようにルートからの相対パスになります。
もし homepage
を設定せずにデプロイした場合、GitHub Pagesはあなたのサイトを https://<YOUR_USERNAME>.github.io/<YOUR_REPOSITORY_NAME>/
というURLで提供します。ブラウザがこのURLにアクセスして index.html
を取得した後、HTML内の /static/js/bundle.js
というパスを解決しようとします。ブラウザはこれを https://<YOUR_USERNAME>.github.io/static/js/bundle.js
と解釈し、リクエストを送信します。
しかし、GitHub Pagesのリポジトリのルートは <YOUR_REPOSITORY_NAME>/
ディレクトリの内容に対応しています。したがって、/static/js/bundle.js
は実際には /<YOUR_REPOSITORY_NAME>/static/js/bundle.js
に配置されるべきです。パスが一致しないため、ブラウザはバンドルファイルを見つけることができず、サイトは正しく表示されません(通常、コンソールに404エラーが表示されます)。
homepage
プロパティに https://<YOUR_USERNAME>.github.io/<YOUR_REPOSITORY_NAME>
を設定することで、ビルドツール(CRAの場合はreact-scripts、Viteの場合はVite自体)は、バンドルファイルへの参照パスをこの homepage
の値を基準とした相対パスに自動的に調整します。例えば、/static/js/bundle.js
というパスは <YOUR_REPOSITORY_NAME>/static/js/bundle.js
のように変換され、GitHub Pagesの提供パスと一致するようになります。
b. デプロイ用スクリプトの追加
gh-pages
パッケージを使って簡単にデプロイを実行できるように、package.json
の scripts
セクションに新しいコマンドを追加します。通常、predeploy
と deploy
という2つのスクリプトを定義します。
predeploy
: デプロイの準備として実行されるスクリプトです。ここでは、Reactアプリケーションを本番向けにビルドするコマンド (npm run build
) を指定します。npm run deploy
を実行する前に、npm
は自動的にpredeploy
という名前のスクリプトを探して実行します。deploy
: 実際のデプロイ処理を実行するスクリプトです。gh-pages
コマンドに、デプロイ対象のビルド済みファイルが含まれるディレクトリを指定します。CRAの場合はbuild
ディレクトリ、Viteの場合はdist
ディレクトリがデフォルトの出力先です。
package.json
の scripts
セクションに以下の2行を追加してください。既存のスクリプト(start
, build
, test
, eject
など)の下に追加するのが一般的です。
json
// package.json の scripts セクション
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"predeploy": "npm run build", // ★ この行を追加 ★
"deploy": "gh-pages -d build" // ★ この行を追加 ★
},
注意: もしViteを使用している場合は、ビルドディレクトリが dist
なので、deploy
スクリプトは以下のようになります。
json
// Vite の場合の deploy スクリプト
"scripts": {
// ... other scripts
"predeploy": "npm run build",
"deploy": "gh-pages -d dist" // Vite の場合は dist を指定
},
これで package.json
の設定変更は完了です。ファイルを保存してください。
ステップ3: GitHubリポジトリの確認とプッシュ
既に「デプロイの準備」のステップでローカルプロジェクトをGitHubリポジトリにプッシュ済みですが、package.json
を変更したので、再度プッシュする必要があります。
変更をステージングエリアに追加し、コミットしてプッシュします。
bash
git add .
git commit -m "Add homepage and deploy scripts for gh-pages"
git push origin main
GitHubリポジトリのページで、package.json
ファイルが更新されていることを確認してください。
ステップ4: デプロイの実行
gh-pages
パッケージと設定が準備できたので、いよいよデプロイを実行します。ターミナルでプロジェクトのルートディレクトリを開き、以下のコマンドを実行します。
npmを使用する場合:
bash
npm run deploy
Yarnを使用する場合:
bash
yarn run deploy
このコマンドを実行すると、以下のことが自動的に行われます。
package.json
のpredeploy
スクリプトが実行されます。これはnpm run build
(またはyarn build
) を実行します。- Reactアプリケーションの本番ビルドが実行され、CRAの場合は
build
ディレクトリ、Viteの場合はdist
ディレクトリに静的ファイルが出力されます。 - ビルドが成功すると、
deploy
スクリプトが実行されます。これはgh-pages -d build
(またはgh-pages -d dist
) を実行します。 gh-pages
コマンドは、指定されたディレクトリ (build
またはdist
) の内容を、自動的にgh-pages
という名前の新しいGitブランチにコピーします。gh-pages
ブランチが作成または更新され、ビルドファイルがそのブランチにコミットされます。- 新しく作成/更新された
gh-pages
ブランチが、リモートのGitHubリポジトリにプッシュされます。
コマンド実行中は、ビルドプロセスのログや、gh-pages
がファイルをコピー・コミット・プッシュしている様子のログがターミナルに表示されます。すべて完了するまでしばらく時間がかかります。
エラーが発生せず、コマンドの実行が正常に終了したことを確認してください。もしエラーが出た場合は、表示されたエラーメッセージをよく読み、原因を特定して対処する必要があります(よくあるエラーについては後述のトラブルシューティングセクションを参照)。
GitHubのウェブサイトであなたのリポジトリページを開き、「Branch」ドロップダウンを見てみてください。main
ブランチに加えて、新しく gh-pages
というブランチが作成されているはずです。gh-pages
ブランチを選択し、その中にあなたのビルドファイル(index.html
, static
フォルダなど)が配置されていることを確認してください。
ステップ5: GitHub Pagesの設定
gh-pages
ブランチにビルドファイルがプッシュされたら、GitHubリポジトリの設定で、このブランチをGitHub Pagesのソースとして指定する必要があります。
- GitHubのあなたのリポジトリページにアクセスします。
- ページ上部にある「Settings」タブをクリックします。
- 左側のサイドバーから「Pages」を選択します(「Code and automation」の下にあることが多いです)。
- 「Build and deployment」セクションを見つけます。
- 「Source」の設定で、デフォルトが「Deploy from a branch」になっていることを確認します。もしGitHub Actionsなど他の設定になっている場合は、「Deploy from a branch」を選択してください。
- その下にある「Branch」の設定ドロップダウンをクリックします。
- 一番左のドロップダウンで、ソースとなるブランチとして「
gh-pages
」を選択します。 - 右側のドロップダウンで、ブランチ内のどのディレクトリを公開するかとして「
/ (root)
」を選択します。これは、gh-pages
ブランチのルートディレクトリにビルドファイルがあるためです。
- 一番左のドロップダウンで、ソースとなるブランチとして「
- 「Save」ボタンをクリックします。
設定を保存すると、GitHub Pagesがデプロイプロセスを開始します。通常、数分以内にサイトが公開されます。
ページをリロードすると、「GitHub Pages source」セクションの上部に「Your site is published at [サイトのURL]」というメッセージと、公開されたサイトのURL(https://<YOUR_USERNAME>.github.io/<YOUR_REPOSITORY_NAME>/
)が表示されます。
もし「Your site is currently being built from the gh-pages branch.」のようなメッセージが表示されている場合は、デプロイ処理が進行中です。しばらく待ってから再度ページをリロードしてください。
ステップ6: デプロイされたアプリケーションの確認
GitHub Pagesの設定画面に表示されたURL、https://<YOUR_USERNAME>.github.io/<YOUR_REPOSITORY_NAME>/
にブラウザでアクセスしてみてください。
あなたのReactアプリケーションが表示されれば、デプロイは成功です!おめでとうございます!
もしアプリケーションが正しく表示されない場合は、以下の点を試してみてください。
- キャッシュのクリア: ブラウザのキャッシュが古いファイルを読み込んでいる可能性があります。スーパーリロード(Windows/Linux:
Ctrl+Shift+R
、macOS:Cmd+Shift+R
)を試すか、ブラウザのキャッシュを完全にクリアしてからアクセスしてください。 - URLの確認: 設定した
homepage
のURLと、実際にアクセスしているURLが一致しているか確認してください。特にリポジトリ名やユーザー名に間違いがないかチェックしましょう。 - 開発者コンソール: ブラウザの開発者ツールを開き、ConsoleタブとNetworkタブを確認してください。JavaScriptエラーが出ていないか、またはCSSやJavaScriptファイルが404エラーになっていないか確認しましょう。もし404エラーが出ている場合は、
homepage
の設定や、ビルドディレクトリの指定(-d build
または-d dist
)が正しいか再確認が必要です。 - GitHub Pages設定の確認: GitHubリポジトリのSettings -> Pagesの設定で、ソースブランチが
gh-pages
、ディレクトリが/ (root)
になっているか再度確認してください。 - gh-pages ブランチの確認: GitHub上で
gh-pages
ブランチを選択し、index.html
やstatic
(CRA) またはassets
(Vite) ディレクトリなどが正しく配置されているか確認してください。ファイルが全くない、あるいは古い内容になっている場合は、npm run deploy
が正常に完了しなかった可能性があります。
これらの確認と対処法については、後述のトラブルシューティングセクションでさらに詳しく解説します。
Viteを使用したReactアプリのデプロイ:CRAとの違い
先ほどはCRAを例に説明しましたが、Viteで作成したReactアプリケーションも gh-pages
を使って同様にGitHub Pagesにデプロイできます。手順はCRAとほとんど同じですが、ビルド出力ディレクトリが異なる点に注意が必要です。
gh-pages
パッケージのインストール: CRAと同じです。
bash
npm install --save-dev gh-pages
# または yarn add --dev gh-pagespackage.json
の設定変更:homepage
プロパティ: CRAと同じように追加します。
json
"homepage": "https://<YOUR_USERNAME>.github.io/<YOUR_REPOSITORY_NAME>",- デプロイ用スクリプト:
predeploy
スクリプトはnpm run build
(またはyarn build
) で同じですが、Viteのデフォルトビルド出力先はdist
ディレクトリなので、deploy
スクリプトの-d
オプションにはdist
を指定します。
json
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"predeploy": "npm run build", // ビルドコマンドは同じ
"deploy": "gh-pages -d dist" // ★ ビルドディレクトリが dist になる ★
},
- GitHubリポジトリへのプッシュ: 変更した
package.json
をプッシュします。
bash
git add .
git commit -m "Configure gh-pages for Vite project"
git push origin main - デプロイの実行: CRAと同じコマンドです。
bash
npm run deploy
# または yarn run deploy
このコマンドにより、Viteビルドが実行され (dist
ディレクトリが出力され)、その内容がgh-pages
ブランチにプッシュされます。 - GitHub Pagesの設定: CRAと同じ手順で、Settings -> Pages に進み、「Source」で
gh-pages
ブランチと/ (root)
ディレクトリを選択し、保存します。 - デプロイされたアプリケーションの確認: 表示されたURLにアクセスして確認します。
このように、Viteを使った場合でも、ビルド出力ディレクトリの違いを deploy
スクリプトで吸収すれば、gh-pages
パッケージを使ったデプロイ手順はほとんど変わりません。Viteのビルドは一般的にCRAよりも高速なので、デプロイ前のビルド時間も短縮されるメリットがあります。
シングルページアプリケーション (SPA) とルーティングの問題:対策
前述したように、ReactのようなSPAはクライアントサイドルーティングを利用しますが、静的ホスティングであるGitHub Pagesでは、特定のパスに直接アクセスした場合に404エラーが発生するという問題があります。例えば、サイトのルート https://<YOUR_USERNAME>.github.io/<YOUR_REPOSITORY_NAME>/
からアプリケーションに入り、内部リンクをクリックして /about
というパスに移動するのは問題ありません。これは、ブラウザの履歴APIを使ってJavaScriptがURLを操作し、コンテンツを動的に書き換えているだけで、GitHub Pagesへの新しいファイルリクエストは発生しないからです。
しかし、ブラウザのアドレスバーに直接 https://<YOUR_USERNAME>.github.io/<YOUR_REPOSITORY_NAME>/about
と入力してアクセスしたり、このURLをブックマークして後から開いたり、他のサイトからこのURLへのリンクをクリックしたりすると、GitHub Pagesは /<YOUR_REPOSITORY_NAME>/about
というパスに対応する物理的なファイルを探そうとします。しかし、SPAでは通常、 /
以外のパスに対応するHTMLファイルは存在しないため、GitHub Pagesはファイルを見つけられず、標準の404 Not Foundページを返してしまいます。
このSPAルーティング問題をGitHub Pagesで解決するには、主に以下の2つの方法があります。
対策1: ハッシュベースのルーティング (HashRouter
) を使用する
最も簡単で確実な方法は、React Routerなどのルーティングライブラリにおいて、ブラウザの履歴API (BrowserRouter
が利用するもの) ではなく、URLのハッシュ (#
) を利用するルーティングモードに切り替えることです。
React Routerの場合、BrowserRouter
の代わりに HashRouter
コンポーネントを使用します。
変更前 (BrowserRouter):
“`jsx
import { BrowserRouter as Router, Route, Routes } from ‘react-router-dom’;
import Home from ‘./pages/Home’;
import About from ‘./pages/About’;
import Contact from ‘./pages/Contact’;
function App() {
return (
);
}
export default App;
“`
変更後 (HashRouter):
“`jsx
import { HashRouter as Router, Route, Routes } from ‘react-router-dom’; // HashRouter をインポート
import Home from ‘./pages/Home’;
import About from ‘./pages/About’;
import Contact from ‘./pages/Contact’;
function App() {
return (
);
}
export default App;
“`
App.js
(またはあなたのアプリケーションのエントリポイントとなるファイル) の中で、ルーターコンポーネントを BrowserRouter
から HashRouter
に変更するだけです。
仕組み:
HashRouter
を使用すると、URLのパス部分は常に index.html
を指し、実際のルーティング情報はURLのハッシュ(#
の後に続く部分)に格納されます。
例えば、/about
へのパスは /#/about
のようになります。
- ユーザーが
https://<YOUR_USERNAME>.github.io/<YOUR_REPOSITORY_NAME>/#/about
にアクセスした場合、ブラウザはhttps://<YOUR_USERNAME>.github.io/<YOUR_REPOSITORY_NAME>/
にファイルリクエストを送信します。 - GitHub Pagesは
index.html
ファイルを返します。 - ブラウザが
index.html
を読み込み、ReactアプリケーションのJavaScriptを実行します。 - React RouterはURLのハッシュ部分 (
#/about
) を見て、/about
パスに対応するコンポーネントをレンダリングします。
ハッシュ (#
) の後に続く部分は、ウェブサーバーに送信されるリクエストには含まれません。ブラウザはハッシュ部分をページ内の特定のセクションへのアンカーとして解釈し、サーバーはハッシュを含まないURLでファイルを提供します。これにより、GitHub Pagesは常に index.html
を提供することができ、その後のルーティングはすべてクライアントサイドのJavaScriptがハッシュを基に行うため、404エラーを回避できます。
メリット:
- 実装が非常に簡単(ルーターコンポーネントを変更するだけ)。
- GitHub Pagesを含む静的ホスティングサービスで確実に動作する。
デメリット:
- URLに常に
#
が含まれるようになり、見た目が少し不自然になる。 #
以降のURLはGoogleなどの検索エンジンのクローラーによっては無視されることがあるため、SPAの各ページを個別にインデックスしたい場合のSEOに不利になる可能性がある(ただし、最近のクローラーはJavaScriptを実行できるため、以前ほど大きな問題ではないという意見もあります)。
シンプルなサイトやポートフォリオなど、SEOがあまり重要でないアプリケーションにとっては、この方法が最も手軽で推奨されます。
変更後は、再度 npm run deploy
(または yarn run deploy
) を実行して、変更を反映させる必要があります。
対策2: 404.html
を利用したリダイレクトトリック
もう一つの方法は、URLにハッシュを含めずに綺麗なURL (BrowserRouter
を使うような形式) を維持しつつ、GitHub Pagesでルーティング問題を解決するトリックです。これは、GitHub Pagesがカスタム 404.html
ページをサポートしていることを利用します。
GitHub Pagesは、リクエストされたパスに対応するファイルが見つからない場合、リポジトリのルートにある 404.html
ファイルを返します。この 404.html
ファイルに、簡単なJavaScriptコードを記述し、現在のパスを維持したままサイトのルート (index.html
) にリダイレクトさせることで、問題を回避します。
仕組み:
- ユーザーが
https://<YOUR_USERNAME>.github.io/<YOUR_REPOSITORY_NAME>/about
に直接アクセスします。 - GitHub Pagesは
/about
に対応するファイルが見つからないため、代わりに404.html
ファイルを返します。 - ブラウザは
404.html
を読み込み、その中に含まれるJavaScriptコードが実行されます。 - JavaScriptは現在のURLパス (
/about
) を取得し、そのパスを維持したままサイトのルートURL (https://<YOUR_USERNAME>.github.io/<YOUR_REPOSITORY_NAME>/
) にリダイレクトします。ただし、単にリダイレクトするとブラウザの履歴が書き換わってしまうため、履歴APIを使ってパスを書き換えないままルートURLに移動させます。
例:window.location.replace
やwindow.history.replaceState
を利用 - ブラウザは
https://<YOUR_USERNAME>.github.io/<YOUR_REPOSITORY_NAME>/
のindex.html
を読み込み、ReactアプリケーションのJavaScriptを実行します。 - React Router (
BrowserRouter
) は現在のURLパスが/about
であることを認識し、/about
に対応するコンポーネントをレンダリングします。
これにより、ユーザーは一度404ページを経由しますが、ほとんどの場合、そのリダイレクトは瞬時に行われるため、ユーザー体験としては問題なく目的のページが表示されたように見えます。そして、URLはハッシュを含まない綺麗な形式のままです。
実装:
-
404.html
ファイルの作成: プロジェクトのpublic
ディレクトリ(CRAの場合)またはルートディレクトリ(Viteの場合)に404.html
という名前のファイルを作成します。このファイルはビルド時にbuild
またはdist
ディレクトリにコピーされます。
404.html
の内容は以下のようになります。“`html
<!DOCTYPE html>
Redirecting…
// 現在のパスを取得
var path = window.location.pathname;
// リポジトリ名部分を削除して、アプリケーション内のパス部分だけを取得
// 例: //about -> /about
var repoName = '/'; // ★ ご自身のレポジトリ名に置き換えてください ★
if (path.startsWith(repoName)) {
path = path.substring(repoName.length);
}
// リダイレクト先のURLを作成(ルートURL + アプリケーション内パス + 元のクエリパラメータとハッシュ)
var redirectUrl = 'https://.github.io/ /' + path + window.location.search + window.location.hash; // ★ ご自身のユーザー名とレポジトリ名に置き換えてください ★ // ブラウザの履歴を書き換えずにリダイレクト // history.replaceState は SPAルーターが利用する履歴APIに干渉する可能性があるため、 // 最終的には window.location.replace を使う方が確実な場合が多いです。 // ただし、location.replace はブラウザの履歴に元の404ページを残しません。 // もう少し洗練されたリダイレクトが必要な場合は、SPAルーターが対応している // 404ページからのパス情報引き継ぎ方法を検討する必要があります。 // 多くの SPAルーターは location.pathname を参照するため、 // そのまま location.replace を使うとパス情報が失われます。 // ここでは、ハッシュを使ってパス情報を引き継ぐ一般的なトリックを紹介します。 // ハッシュを使ってパス情報を引き継ぐ方法 // 例: /about -> /#/about としてルートにリダイレクト var target = window.location.pathname; var segments = target.split('/').filter(segment => segment !== ''); var repoIndex = segments.indexOf('<YOUR_REPOSITORY_NAME>'); // ★ ご自身のレポジトリ名に置き換えてください ★ if (repoIndex !== -1 && segments.length > repoIndex + 1) { var appPath = segments.slice(repoIndex + 1).join('/'); // ルートURL + /#/ + アプリケーション内パス + クエリパラメータ + 元のハッシュ window.location.replace('https://<YOUR_USERNAME>.github.io/<YOUR_REPOSITORY_NAME>/#' + appPath + window.location.search + window.location.hash); // ★ ご自身のユーザー名とレポジトリ名に置き換えてください ★ } else { // リポジトリ名が含まれない、またはルートパスへのアクセス(本来は404にならないが念のため) window.location.replace('https://<YOUR_USERNAME>.github.io/<YOUR_REPOSITORY_NAME>/' + window.location.search + window.location.hash); // ★ ご自身のユーザー名とレポジトリ名に置き換えてください ★ } // 注意: 上記のJavaScriptコードは、リポジトリ名がパスのどこかに含まれることを前提とした一般的なトリックです。 // 環境や要件によってはより複雑なロジックが必要になる場合があります。 // 例えば、カスタムドメインを使っている場合はリポジトリ名部分は不要になります。 // また、クエリパラメータやハッシュを正しく引き継ぐ必要があります。 // ここでのコードはあくまで基本的な例として提供しています。 // 多くの場合は、gh-pages-spa のような既存のソリューションを利用するか、 // より単純に HashRouter を利用することを検討してください。 // 例外的なシンプルバージョン(HashRouterに依存せず、履歴も気にしない場合) // window.location.replace('https://<YOUR_USERNAME>.github.io/<YOUR_REPOSITORY_NAME>/' + window.location.pathname + window.location.search + window.location.hash); // ★ ご自身のユーザー名とレポジトリ名に置き換えてください ★ // 上記コードでは、location.pathname がリポジトリ名を含んだ '/<YOUR_REPOSITORY_NAME>/about' のようになるため、 // ルートからの絶対パス指定をしているSPAルーターでは上手く機能しません。 // より堅牢な solution: https://github.com/rafgraph/spa-github-pages // このライブラリは、GitHub PagesでのSPAルーティング問題を解決するための専用スクリプトを提供しています。 // 404.html ファイルを作成し、ビルドディレクトリにコピーし、 // その404.htmlで提供されるJavaScriptがパスを処理する仕組みです。 // npm i -D spa-github-pages // package.json に "postbuild": "npm run gh-pages-spa" または "postbuild": "react-app-rewired gh-pages-spa" (customize-cra使用時) // あるいは、404.html を手動で public/ に配置し、その中に以下の様なリダイレクトコードを記述します。 // window.location.replace(window.location.protocol + "//" + window.location.host + window.location.pathname.split('/').slice(0, 2).join('/') + '/?p=' + window.location.pathname.slice(1).replace(/\//g, '~') + window.location.search + window.location.hash); // このトリックはURLをエンコードしてクエリパラメータとして渡し、index.html側のJSでそれを読み取るというものです。 // 404.html を利用したリダイレクトトリックは、HashRouter よりも複雑になることが多いです。 // ここでは、シンプルにルートURLへリダイレクトするだけのコード例を示します。 // これだけではSPAルーターは正しくパスを認識できませんが、404.html の基本的な使い方を示します。 // window.location.replace('https://<YOUR_USERNAME>.github.io/<YOUR_REPOSITORY_NAME>/'); // ★ ご自身のユーザー名とレポジトリ名に置き換えてください ★ // 最終的な結論として、404.htmlトリックはSPAライブラリや構成によって複雑になるため、 // 多くの場合 HashRouter の使用、または専用ライブラリ (spa-github-pages) の使用が推奨されます。 // spa-github-pages を使うと、上記の複雑なJSを書く代わりに、簡単なnpmスクリプトを追加するだけで済みます。 // spa-github-pages を使う場合は、BrowserRouter をそのまま使えます。 // ** spa-github-pages を利用する場合の 404.html に含まれるスクリプト例 (簡略版)** // <script> // sessionStorage.redirect = location.href; // </script> // <meta http-equiv="refresh" content="0;URL='<YOUR_HOMEPAGE_URL>'"> // 例: https://<YOUR_USERNAME>.github.io/<YOUR_REPOSITORY_NAME>/ // これは sessionStorage に元のURLを保存し、ルートにリダイレクトします。 // そして index.html 側のJavaScriptで sessionStorage.redirect をチェックし、 // 値があればそのURLに client-side redirect するという方法です。 // spa-github-pages パッケージはこの処理を自動化してくれます。 // したがって、もし BrowserRouter を使いたいなら、HashRouter より spa-github-pages の利用を強くお勧めします。 // 本記事ではHashRouterの説明をメインとし、404.html は簡単な紹介に留めます。 // 以下のシンプルなリダイレクトは、あくまで「404.htmlが呼ばれたら何かしらのページに戻す」例であり、 // SPAルーター連携には工夫が必要であることを理解してください。 window.location.replace('https://<YOUR_USERNAME>.github.io/<YOUR_REPOSITORY_NAME>/'); // ★ ご自身のユーザー名とレポジトリ名に置き換えてください ★ </script>
Redirecting to site...
``
**重要**: 上記コード内のと
は、必ずあなたのGitHubユーザー名とリポジトリ名に置き換えてください。また、コメントで述べたように、この
404.htmlを利用したトリックは、SPAのルーティングライブラリがパス情報をどのように扱うかによって実装が変わり得る複雑な方法です。最も簡単なのは HashRouter ですが、もしBrowserRouterを使いたい場合は、
spa-github-pagesのような専用ライブラリの利用を強く推奨します。上記の
404.html` コードは、簡単なリダイレクトの概念を示すためのものであり、そのままReact RouterのBrowserRouterで期待通りに動作するとは限りません。 -
ビルドディレクトリへの
404.html
の配置:404.html
を作成したら、ビルドプロセスで生成されるディレクトリ (build
またはdist
) のルートにこのファイルが含まれるようにします。CRAやViteのデフォルト設定では、public
ディレクトリに置いたファイルはビルド出力ディレクトリのルートに自動的にコピーされます。したがって、CRAの場合はpublic/404.html
に、Viteの場合はプロジェクトのルートにある404.html
(Viteのpublicディレクトリはプロジェクトルート)に配置すればOKです。 -
gh-pages
でのデプロイ:gh-pages -d build
(またはdist
) コマンドは、デフォルトではドットファイル(.
で始まるファイル)をコピーしません。404.html
はドットファイルではありませんが、確実に含まれるように--dotfiles
オプションを追加するか、GitHub Pagesが.nojekyll
ファイルを必要とする場合なども考慮し、.nojekyll
ファイルを含めるために--dotfiles
オプションを使用することが推奨される場合があります。ただし、GitHub Pagesは最近.nojekyll
がなくてもSPAを正しく扱うようになったという情報もあり、ほとんどの場合は-d build
(または-d dist
) だけで404.html
も含めてデプロイされます。念のため、gh-pages
コマンドのオプションを確認すると良いでしょう。
もし404.html
がデプロイされない場合は、deploy
スクリプトを以下のように変更してみることを検討してください。
json
// package.json の scripts セクション
"deploy": "gh-pages -d build --dotfiles" // --dotfiles オプションを追加
または、ビルド後に手動で404.html
をgh-pages
ブランチに追加してからプッシュするなどの方法も考えられますが、これはgh-pages
パッケージの自動化のメリットを損ないます。 -
デプロイ:
npm run deploy
(またはyarn run deploy
) を実行し、GitHub Pagesの設定を確認します。
メリット:
- URLに
#
が含まれない、綺麗なURL構造を維持できる。 - SEOに対してより友好的である可能性がある(ただし、クローラーがリダイレクトやJavaScript実行を正しく処理できる場合に限る)。
デメリット:
- 実装が HashRouter に比べて複雑になりがち。特に
404.html
内のJavaScriptコードは、リポジトリ構造や使用するルーティングライブラリによって調整が必要になる場合がある。 - アクセス時に一瞬リダイレクトが発生する(ただし、通常は高速で気づきにくい)。
- リダイレクトコードの実装ミスがあると、かえってデプロイされたサイトが不安定になる可能性がある。
- 最も簡単な
404.html
のトリック(spa-github-pages
ライブラリが実装しているような方法)を使う場合でも、HashRouter よりは少し複雑な設定が必要になる。
どちらの方法を選ぶべきか?
もしSPAルーティングの綺麗なURL構造が絶対的に必要で、SEOへの考慮もしたい場合は、404.html
トリック、特に spa-github-pages
のような既存のライブラリを利用する方法を検討する価値があります。しかし、最も簡単で確実に機能させたいのであれば、迷わず HashRouter
を使用することをお勧めします。ほとんどの個人プロジェクトやデモサイトでは、URLに #
が含まれていても大きな問題にならないでしょう。
対策を実装したら、再度 npm run deploy
を実行し、GitHub Pagesの設定を確認した後、公開されたURLで様々なパス(ルート以外のパスへの直接アクセスを含む)を試して、ルーティングが正しく機能するかを十分にテストしてください。
GitHub Pagesデプロイにおけるその他の注意点とトラブルシューティング
デプロイ作業中に予期せぬ問題が発生することはよくあります。ここでは、GitHub PagesへのReactアプリデプロイで遭遇しやすい問題とその解決策、そしてその他の注意点について説明します。
よくあるトラブルシューティング
-
デプロイしたサイトが真っ白になる、またはCSS/画像が表示されない:
- 原因: 最も可能性が高いのは、
package.json
のhomepage
プロパティが正しく設定されていないか、あるいは設定後に再ビルド・再デプロイをしていないことです。homepage
がない、または間違っていると、ビルドされたHTML内の資材参照パスが相対パス (/static/...
) になり、GitHub Pagesのサブディレクトリ構成 (/<repository-name>/
) の下でファイルが見つからなくなります。 - 解決策:
package.json
のhomepage
がhttps://<YOUR_USERNAME>.github.io/<YOUR_REPOSITORY_NAME>
の形式で正しく設定されていることを確認してください。設定が正しければ、必ずnpm run deploy
(またはyarn run deploy
) を再実行してください。このコマンドはpredeploy
でビルドをやり直し、homepage
設定がビルド結果に反映されます。デプロイ後、ブラウザのキャッシュをクリアしてからアクセスし直してください。開発者ツールのNetworkタブで、資材ファイル(JS, CSS, 画像など)が404になっていないか確認しましょう。
- 原因: 最も可能性が高いのは、
-
ルート以外のパスに直接アクセスすると404エラーになる:
- 原因: これは前述のSPAルーティング問題です。GitHub Pagesは
/about
のようなパスに対応する物理ファイルを見つけられません。 - 解決策: 対策セクションで説明したように、
HashRouter
を使用するか、404.html
を利用したリダイレクトトリック(spa-github-pages
ライブラリの使用を推奨)を実装してください。変更後、必ず再デプロイが必要です。
- 原因: これは前述のSPAルーティング問題です。GitHub Pagesは
-
npm run deploy
コマンドがエラーで終了する:- 原因: 様々な原因が考えられます。
- ビルドエラー:
predeploy
スクリプトとして実行されるnpm run build
が失敗している可能性があります。ビルドエラーのログをよく確認してください。コードに構文エラーがあったり、依存関係に問題があったりする場合に発生します。ローカルでnpm run build
を単独で実行してみて、エラーの詳細を確認するのが良いでしょう。 - Gitエラー:
gh-pages
パッケージは内部でGitコマンドを実行します。Gitの設定がおかしい、リモートリポジトリにアクセスできない、認証エラーなどが考えられます。 gh-pages
エラー: パッケージのバグや環境の問題もゼロではありません。npmパッケージを再インストールしてみたり、GitHubのStatusページで障害情報を確認したりすることが有効な場合があります。
- ビルドエラー:
- 解決策: エラーメッセージを詳細に読み、どのステップ(ビルド、Git操作、
gh-pages
実行)でエラーが発生しているかを特定します。ビルドエラーであればコード修正や依存関係の見直しが必要です。Gitエラーであれば、リモートURLや認証情報(SSHキーやPersonal Access Tokenなど)を確認します。
- 原因: 様々な原因が考えられます。
-
GitHub Pagesの設定画面で
gh-pages
ブランチが選択肢に表示されない:- 原因:
npm run deploy
が正常に完了し、gh-pages
ブランチがGitHubにプッシュされていない可能性があります。 - 解決策: ターミナルの
npm run deploy
の出力ログを確認し、エラーが出ていないかチェックします。GitHubのウェブサイトでリポジトリページを開き、「Branch」ドロップダウンにgh-pages
が存在し、その内容がビルドファイルになっているか確認します。もしブランチがない、または内容が空の場合は、デプロイコマンドが失敗しているか、ローカルのgh-pages
ブランチをリモートにプッシュできていない可能性があります。git branch -a
でローカルとリモートのブランチを確認し、git push origin gh-pages
を手動で実行してみることも有効です。
- 原因:
-
GitHub Pagesのサイトが更新されない:
- 原因: デプロイは成功しているが、ブラウザのキャッシュが古いバージョンを表示している、またはGitHub Pages側のCDN反映に時間がかかっている可能性があります。
- 解決策: ブラウザのスーパーリロード (
Ctrl+Shift+R
/Cmd+Shift+R
) を試します。それでもダメな場合は、ブラウザのキャッシュを完全にクリアします。GitHub Pagesはデプロイ後すぐに反映されないこともありますので、数分〜十数分待ってから再度アクセスしてみることも有効です。
-
ファイル名やパスの大文字・小文字が区別される:
- 原因: WindowsやmacOSの一部のファイルシステム設定では、ファイル名の大文字・小文字が区別されません(例:
Image.png
とimage.png
は同じファイルとして扱われる)。しかし、GitHub Pagesが動作しているサーバー(通常Linux)では、大文字・小文字は厳密に区別されます。ローカルでは動いていたが、デプロイ後に画像やCSSが読み込めなくなる原因の1つです。 - 解決策: プロジェクト内のファイル名や、それらをコード内で参照しているパスにおいて、大文字・小文字が完全に一致しているか確認してください。特に画像ファイル名などで起こりやすいミスです。すべてのファイル名やパスを小文字に統一するなどのルールを設けると、この種の問題を避けやすくなります。
- 原因: WindowsやmacOSの一部のファイルシステム設定では、ファイル名の大文字・小文字が区別されません(例:
その他の注意点
.gitignore
ファイル: Reactプロジェクトには通常.gitignore
ファイルがあり、node_modules
やビルドディレクトリ (build
/dist
) をGit管理から除外しています。gh-pages
パッケージは、.gitignore
の設定に関わらず、指定されたビルドディレクトリの中身を新しいブランチにコピーしてプッシュします。したがって、通常は.gitignore
の設定を気にする必要はありません。- Privateリポジトリ: GitHub Freeプランの場合、GitHub PagesはPublicリポジトリでのみ利用できます。PrivateリポジトリでGitHub Pagesを利用したい場合は、GitHub Pro以上の有料プランが必要です。
- ビルド時間の考慮: 大規模なReactアプリケーションの場合、ビルドに時間がかかることがあります。
predeploy
スクリプトで実行されるビルドが完了するまで、gh-pages
コマンドは待ちます。 - 環境変数の扱い: Create React AppやViteは、
.env
ファイルなどを使ってアプリケーション内で環境変数を利用できます。ビルド時にこれらの環境変数を組み込む方法については、それぞれのツールのドキュメントを確認してください。GitHub Pagesは静的ホスティングなので、ビルド時に確定する静的な環境変数のみを扱うのが一般的です。サーバーサイドで動的に決定される環境変数は利用できません。 - セキュリティ: GitHub Pagesで公開されるコードやAPIキーなどの情報は、すべて静的なファイルとしてブラウザからアクセス可能になります。重要な秘密情報(APIキーなど)をクライアントサイドのコードに直接ハードコーディングすることは避けてください。APIキーが必要な場合は、バックエンドサーバー(例: Netlify Functions, AWS Lambdaなど)を介して安全に処理する必要があります。GitHub Pagesはあくまで静的サイト向けであることを理解しておく必要があります。
これらの注意点とトラブルシューティングの知識があれば、GitHub Pagesへのデプロイ作業をよりスムーズに進められるはずです。
自動化への次のステップ:GitHub Actions
gh-pages
パッケージを使ったデプロイは手軽ですが、新しい変更を公開するたびに npm run deploy
コマンドを手動で実行する必要があります。開発中は頻繁にコードを変更するため、この手動プロセスが面倒に感じられるかもしれません。
そこで次のステップとして検討したいのが、GitHub Actionsを使ったデプロイの自動化です。GitHub Actionsは、GitHub上で様々なワークフローを自動化できるCI/CDサービスです。例えば、「main
ブランチにコードがプッシュされたら、自動的にアプリケーションをビルドし、GitHub Pagesにデプロイする」といったワークフローを設定できます。
GitHub Actionsを利用する場合でも、gh-pages
パッケージをワークフロー内で利用する方法と、GitHubが提供する actions/upload-pages-artifact
や actions/deploy-pages
といった公式Actionsを利用する方法があります。
gh-pages
パッケージをGitHub Actionsで利用する基本的な流れ:
- リポジトリの
.github/workflows
ディレクトリにYAMLファイルを作成します(例:deploy.yml
)。 - YAMLファイルで、ワークフローをトリガーするイベント(例:
push
tomain
ブランチ)を定義します。 - ジョブの中で、Node.jsのセットアップ、依存関係のインストール (
npm install
)、ビルド (npm run build
)、そしてgh-pages
コマンドの実行 (npm run deploy
) といったステップを記述します。gh-pages
コマンドの実行には、GitHub Actionsで提供されるGitHubトークンを使って認証を行います。
```yaml
.github/workflows/deploy.yml の例
name: Deploy to GitHub Pages
on:
push:
branches:
- main # main ブランチへのプッシュをトリガーとする
jobs:
build-and-deploy:
runs-on: ubuntu-latest # GitHub Actions が実行される環境を指定
steps:
- name: Checkout code
uses: actions/checkout@v4 # リポジトリのコードをチェックアウト
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '18' # 使用する Node.js のバージョンを指定
- name: Install dependencies
run: npm ci # 依存関係をインストール (npm ci はよりクリーン)
- name: Build application
run: npm run build # アプリケーションをビルド
- name: Deploy to GitHub Pages
run: npm run deploy # package.json で定義した deploy スクリプトを実行
env:
# gh-pages パッケージが必要とする場合に備えて GH_TOKEN を設定
# actions/checkout@v4 が自動でトークンを設定する場合もある
# SSH経由でgit pushする場合は別途設定が必要
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} # GitHub Actions が自動で提供するトークン
# gh-pages がユーザー名やリポジトリ名を自動で取得できない場合に
# ENV に GH_PAT や GH_TOKEN を設定して認証させる必要がある場合がある。
# 通常は actions/checkout と actions/setup-node で十分。
# もし必要なら package.json の deploy スクリプトを
# "deploy": "GH_TOKEN=${{ secrets.GITHUB_TOKEN }} gh-pages -d build" のように調整
# または gh-pages コマンドで認証情報を指定する
# 例: gh-pages -d build -r https://${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git
# 補足:最新のGitHub Pages Actions (actions/deploy-pages) を使う方が推奨される場合が多いです。
# actions/upload-pages-artifact と actions/deploy-pages は gh-pages ブランチを直接いじるのではなく、
# ビルド成果物をアップロードし、それを GitHub Pages がデプロイするという仕組みです。
# この方法の場合、Settings -> Pages の Source を "GitHub Actions" に変更する必要があります。
# actions/upload-pages-artifact & actions/deploy-pages を使う場合の例(gh-pages パッケージは不要)
# - name: Upload artifact
# uses: actions/upload-pages-artifact@v3
# with:
# path: './build' # または './dist'
# - name: Deploy to GitHub Pages
# id: deployment
# uses: actions/deploy-pages@v4
# with:
# token: ${{ secrets.GITHUB_TOKEN }}
```
上記のYAMLはあくまで基本的な概念を示すものであり、実際のReactプロジェクト構成や必要なNode.jsバージョン、認証方法によって調整が必要です。特に gh-pages
パッケージをGitHub Actionsで使う場合の認証設定は、状況によって異なる場合があります。
GitHub Actionsは非常に強力で柔軟なツールであり、デプロイ以外にもコードの静的解析、テストの実行、ビルド結果のチェックなど、様々なワークフローを構築できます。手動でのデプロイに慣れたら、ぜひGitHub Actionsを使った自動化に挑戦してみてください。これにより、開発サイクルが大幅に効率化されます。GitHub Pagesの設定で、Sourceを「Deploy from a branch」から「GitHub Actions」に切り替えることで利用可能になります。
まとめ:Reactアプリの公開、成功への道
この記事では、ReactアプリケーションをGitHub Pagesにデプロイするための詳細な手順を、gh-pages
パッケージを中心に解説しました。
- 準備: Reactプロジェクト、Git、GitHubアカウント、およびリポジトリを用意しました。
gh-pages
の設定: パッケージをインストールし、package.json
にhomepage
とデプロイ用スクリプトを追加しました。homepage
の設定が、GitHub Pagesのサブディレクトリ構成で正しく資材を読み込むためにいかに重要か、その理由を詳しく説明しました。- デプロイ実行:
npm run deploy
コマンド一つで、ビルドからgh-pages
ブランチへのプッシュまでを自動で行いました。 - GitHub Pages設定: GitHubリポジトリの設定画面で、デプロイソースとして
gh-pages
ブランチを指定しました。 - 確認: 公開されたURLでアプリケーションが正しく表示されることを確認しました。
- Vite対応: CRAとViteでのビルド出力ディレクトリの違いに基づいた
deploy
スクリプトの調整方法を説明しました。 - SPAルーティング問題: 静的ホスティングであるGitHub PagesとSPAのクライアントサイドルーティングの間に発生する問題(特定のパスへの直接アクセスで404になる)を説明し、
HashRouter
を使う方法と404.html
を利用するトリックの2つの対策を提示しました。それぞれのメリット・デメリットを比較し、多くの場合HashRouter
が最も簡単であることを示唆しました。 - トラブルシューティング: デプロイでよく発生する問題(真っ白な画面、404エラー、デプロイ失敗など)の原因と解決策を詳細に解説しました。ファイル名の大文字・小文字の問題など、見落としがちな点にも触れました。
- 自動化: 手動デプロイからの次のステップとして、GitHub Actionsを使ったデプロイ自動化の可能性について簡単に触れました。
GitHub Pagesは、特にフロントエンド開発者にとって、ポートフォリオサイトや小規模なプロジェクト、デモサイトなどを手軽に公開するための強力なツールです。Reactのようなモダンなフレームワークで構築されたアプリケーションも、適切な設定と理解があれば、GitHub Pages上で問題なく動作させることができます。
この記事で学んだ手順と知識を活用すれば、あなたのReactアプリケーションを簡単にインターネット上に公開し、より多くの人に見てもらうことができるでしょう。デプロイは開発プロセスにおける重要なステップの一つです。成功体験を重ねることで、さらに自信を持って開発に取り組めるようになります。
GitHub Pagesは静的サイトのホスティングに特化しているため、本格的なウェブアプリケーションでバックエンドAPIやデータベース連携が必要な場合は、Netlify, Vercel, Firebase Hosting, AWS S3/CloudFront, Renderなどの他のホスティングサービスを検討する必要があります。これらのサービスは、静的サイトのホスティングに加えて、サーバーレス関数(API)、データベース、認証などの機能を提供しているものが多いです。しかし、まずは手軽にReactアプリを公開したいという目的であれば、GitHub Pagesは素晴らしいスタート地点となるでしょう。
この記事が、あなたのReact開発とデプロイの助けとなれば幸いです。Happy Coding & Happy Deploying!
参考資料
- Create React App Deployment: https://create-react-app.dev/docs/deployment/
- Vite Deployment: https://vitejs.dev/guide/static-deploy.html#github-pages
gh-pages
npm package: https://www.npmjs.com/package/gh-pages- GitHub Pages documentation: https://docs.github.com/en/pages
- SPA routing on GitHub Pages (
spa-github-pages
): https://github.com/rafgraph/spa-github-pages