ReactアプリをVercelに載せる方法は、Gitリポジトリを連携する方法、手元からVercel CLIで送る方法、GitHub Actionsでビルドしてから送る方法の3つです。どれを選んでも、つまずく場所はほぼ決まっています。新規プロジェクトの初回は--prodを付けなくても本番になること、Vite製のReact SPAは下位ページを直接開くと404になること、そしてプレビューURLを共有すると相手にログイン画面が出ることです。この記事では、Vercel CLI 65.4.0(2026年10月27日公開)とVite 8.3.5でvercel buildの出力を確かめた結果をもとに、手順と直し方を順に示します。Vercelそのものの仕組みはVercel(ヴァーセル)とは?サーバー不要の仕組みとできること・料金【2026年】で解説しています。
まとめ
- 継続して開発するアプリはGit連携が基本です。GitHub・GitLab・Bitbucketのリポジトリをimportすると、Viteなら
vite buildと出力先distが自動で入ります。 - CLIは
npm i -g vercel(Node.js 20以上)で入れ、vercelでプレビュー、vercel --prodで本番に出します。ただし新規プロジェクトの初回は、--prodを省いても本番デプロイになります。 - Vite製のReact SPAは、Viteプリセットの既定ルートが
/api以外の存在しないパスを404に送るため、直リンクで404になります。vercel.jsonのrewritesで/index.htmlへ向ければ直り、JSやCSSの配信は壊れません。 - テストや承認を挟みたいときだけGitHub Actionsを使い、
vercel pull→vercel build→vercel deploy --prebuiltの順で送ります。Git連携を残すと同じコミットで2回デプロイされます。 - ビルドのNode.jsは既定が24.xで、選べるのは24.xと22.xです。Node.js 20は2026年10月1日から新規デプロイに使えません。
- Hobby(無料)は非商用の個人利用に限られます。本番も含めた非公開設定は、2026年9月9日から全プランで追加料金なしで使えます。
デプロイ方法の選び方(Git連携・CLI・GitHub Actions)
3つの方法は併用でき、Git連携をつないだまま手元からCLIで出すこともできます。迷ったらGit連携から始め、テストの合否でデプロイを止めたくなった時点でGitHub Actionsに切り替えるのが手戻りの少ない順番です。
| 観点 | Git連携 | Vercel CLI | GitHub Actions |
|---|---|---|---|
| ビルドする場所 | Vercel | Vercel(--prebuiltなら手元) |
Actionsのランナー |
| デプロイの契機 | push・マージ | コマンド実行 | ワークフロー |
| PRへのURL投稿 | 自動 | なし | 自前のステップ |
| テスト・承認の関門 | なし | なし | 組める |
| 向く場面 | 継続開発・チーム | 動作確認・単発公開 | 品質ゲートが要る案件 |
Next.jsとVite製React SPAでは、デプロイの手順は同じでも、ビルドの既定値、環境変数の接頭辞、直リンク404の対策が違います。Next.js自体の始め方はNext.jsとは?16系App Routerで最小アプリを動かす手順と採用判断を参照してください。
Git連携でのデプロイ手順(GitHub・GitLab・Bitbucket)
リポジトリのimportとViteプリセットの既定値
ダッシュボードで「Add New…」から「Project」を選び、Gitホスティングを連携してリポジトリをimportします。VercelのGit連携の対象はGitHub・GitLab・Bitbucketに加え、Azure DevOps Pipelines(Vercel Deployment Extension経由)とCursorのOriginです。Originは研究プレビューで、Hobbyのチームからはデプロイできません。
importすると、Vercelはpackage.jsonからフレームワークを判別してFramework Presetを埋めます。主な既定値は次のとおりです。
| 項目 | Vite(React) | Next.js | Create React App |
|---|---|---|---|
| Build Command(既定値) | vite build |
next build |
react-scripts build |
| Output Directory | dist |
自動(指定不要) | build |
| 直リンク404の対策 | rewritesが必要 | 不要 | 不要(プリセットが対応) |
Build Commandの欄はプリセットの既定値で、package.jsonにbuildスクリプトがあればそちらが走ります。create-viteのテンプレートはtsc -b && vite buildなので、型エラーがあるとVercel上のビルドも失敗します。設定を確認して「Deploy」を押すとビルドが始まり、完了すると.vercel.appで終わるURLが表示されます。
アプリがリポジトリのサブディレクトリにある場合(モノレポ)は、Root Directoryにそのディレクトリを指定します。Create React AppはReact公式が2025年2月14日に新規アプリでの利用を非推奨にしており、これから作るならViteかフレームワークを選びます。既存のCRAプロジェクトは、出力先がbuildになる点を読み替えればそのままデプロイできます。CRAのプリセットは存在しないパスをindex.htmlへ返すルートを最初から持っているので、rewritesは要りません。環境変数の接頭辞はREACT_APP_です。
新しくViteのReactアプリを作るコマンドはnpm create vite@latest my-app -- --template react-tsです。2026年10月27日に公開されたcreate-vite 9.3.2は、npmに上がった配布物のファイル数が5件しかなく(9.3.1は242件)、手元ではENOENT(template-react-tsが見つからない)で止まりました。同じ症状が出たらnpm create [email protected]のように版を指定すると作成できます。
本番ブランチとプレビューの自動デプロイ
連携後は、本番ブランチへのpushやマージがProductionデプロイ、それ以外のブランチやPull RequestへのpushがPreviewデプロイになります。本番ブランチは、新規プロジェクトの作成時にmain、master、Bitbucketの本番ブランチ設定、リポジトリの既定ブランチの順で選ばれます。developを本番にしたい場合はプロジェクト設定で変更します。
プレビューのURLはPull Requestにコメントとして自動投稿されます。ビルドとテストを分けたい事情がなければ、GitHub Actionsを別に組む必要はありません。Vercel公式のGitHub Actionsガイドも、テスト・脆弱性スキャン・性能予算・人の承認のどれかが要るときだけActionsを使うよう勧めています。
Vercel CLIでのデプロイ手順
CLIのインストールとログイン
npmのvercelパッケージの最新は65.4.0(2026年10月27日公開)で、enginesはnode >= 20です。グローバルに入れてログインします。
npm i -g vercel
vercel --version # 2026年10月27日の確認時は 65.4.0
vercel login
vercel loginはブラウザでの認証に進み、完了するとCLIがアカウントに紐づきます。グローバルに入れたくない場合は、毎回npx vercelやnpx vercel --prodと打てば同じ操作になります。
初回は本番、2回目以降は vercel がプレビュー
プロジェクトのルートでvercelを実行すると、初回はプロジェクト名やスコープを対話で確認し、.vercel/project.jsonを作ってプロジェクトに紐づけます。初回の扱いには例外があり、Vercelのドキュメントは、新規プロジェクトの最初のデプロイは--prodを省いても、--target=previewを付けても本番になると明記しています。失敗した初回も1回目に数えます。
vercel # 2回目以降はプレビュー(初回だけは本番)
vercel --prod # 本番ドメインへデプロイ
vercel --prod --skip-domain # 本番ビルドは作るがドメインはまだ切り替えない
作りかけの画面を本番URLに出したくない場合は、最初は中身の無いページで1回出しておきます。2回目以降はvercelのプレビューURLで表示を確かめてから--prodで出す、という順番で運用できます。--skip-domainで作った本番ビルドは、確認後にvercel promoteでドメインを割り当てます。
アカウント不要の一時デプロイ(temporaryオプション)
CLIに認証情報が無い状態なら、vercel deploy --temporaryでログインせずにデプロイできます。CLIが手元でビルドしてから送り、対象は常に本番です。表示される引き取り用のURL(claim URL)で期限内にアカウントへ引き取らないと、期限切れで消えます。CI環境や、すでにVercelのプロジェクトに紐づいたディレクトリでは使えません。claim URLを知っている人は誰でもプロジェクトを引き取れるので、共有しないでください。
Vite製React SPAの直リンク404対策
404になる仕組み(vercel build の出力で確認)
Vite製のReactアプリにreact-routerなどのクライアント側ルーティングを入れると、トップから画面遷移する分には問題なく動くのに、/aboutを直接開いたりリロードしたりすると404になります。原因は、Viteプリセットが組み立てるルーティングにあります。Vercel CLI 65.4.0のvercel buildでVite 8.3.5のアプリを組むと、.vercel/output/config.jsonには次のルートだけが出力されました。
"routes": [
{ "handle": "error" },
{ "status": 404, "src": "^(?!/api).*$", "dest": "/404.html" }
]
ファイルとして存在しないパスは、/apiで始まるものを除いてすべて/404.htmlへ送られます。distには/aboutに当たるHTMLファイルが無いので、/aboutはReactに届く前に404で終わります。vercel buildはログインしていなくても、.vercel/project.jsonがあれば手元で動き、デプロイ前にこの出力を確かめられます。
vercel.jsonのrewritesによるindex.htmlへの書き換え
プロジェクトのルートにvercel.jsonを置き、すべてのパスを/index.htmlへ書き換えます。VercelのVite向けドキュメントが示している設定と同じです。
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"rewrites": [
{ "source": "/(.*)", "destination": "/index.html" }
]
}
この設定で組み直すと、ルートは次のように変わりました。
"routes": [
{ "handle": "filesystem" },
{ "src": "^(?:/(.*))$", "dest": "/index.html", "check": true },
{ "handle": "error" },
{ "status": 404, "src": "^(?!/api).*$", "dest": "/404.html" }
]
先頭の"handle": "filesystem"は、実在するファイルを先に返す段です。/assets/index-xxxx.jsのようにビルドで出力されたファイルはここで返り、rewritesに入るのは存在しないパスだけです。全パスを書き換えてもJSやCSSがindex.htmlに化けないのはこのためです。
注意点が2つあります。cleanUrlsをtrueにしている場合は、destinationを/と拡張子なしで書きます。存在しないURLにもindex.htmlが200で返るので、該当なしの画面はReact側で用意します。Next.jsはプリセットがページごとのルーティングを組み、Create React Appはプリセットにindex.htmlへのフォールバックが入っているので、どちらもこの設定は不要です。
GitHub Actionsからのデプロイ手順(vercel buildとprebuilt)
必要なSecretと .vercel/project.json
Actionsからデプロイするには、リポジトリのSecretsに3つの値を登録します。VERCEL_TOKENはアカウントのトークン画面かvercel tokens addで作ります。VERCEL_ORG_IDとVERCEL_PROJECT_IDは、手元でvercel linkしたときにできる.vercel/project.jsonのorgIdとprojectIdです。トークンをワークフローのYAMLに直接書くと、リポジトリを読める人全員に渡ります。
ワークフロー例と二重デプロイの止め方
公式ガイドの本番用ワークフローは次の形です。プレビュー用は--environment=previewにして、buildとdeployから--prodを外し、トリガーをmain以外のブランチにします。
name: Vercel Production Deployment
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
on:
push:
branches:
- main
jobs:
Deploy-Production:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Vercel CLI
run: npm install --global vercel@latest
- name: Pull Vercel Environment Information
run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
- name: Build Project Artifacts
run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
- name: Deploy Project Artifacts to Vercel
run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
vercel pullが環境変数とプロジェクト設定を.vercelに取り込み、vercel buildがランナー上で.vercel/outputを作り、--prebuiltがその成果物だけを送ります。テストは同じジョブのbuildとdeployの間にステップとして足します。別のジョブに分けるなら、デプロイのジョブにneedsを付けてテストの成功を待たせ、.vercel/outputはアーティファクトで受け渡すか、デプロイのジョブで組み直します。--prebuiltを付けずにvercel deployすると、Vercel側でも同じビルドがもう一度走り、ビルドの時間と待ちが重なります。
Git連携をつないだままActionsを足すと、同じpushで両方がデプロイします。vercel.jsonに"git": { "deploymentEnabled": false }を書いて、Git連携側の自動デプロイを止めます。もう1つの違いは、--prebuiltではビルド時にVercelのシステム環境変数(VERCEL_ENVなど)が入らないことです。ビルド中にそれを読むコードがあるなら、Actions側で値を渡します。Next.jsでSkew Protectionを使う場合はカスタムのデプロイIDの設定が必要で、背景はVersion Skew(バージョンスキュー)とは?原因とNext.js・Vercelでの対策を実測で解説にまとめています。テストや承認を含むパイプラインを社内に定着させる段階では、DevOps・CI/CD導入支援でも構成の設計から支援しています。
Node.jsの版と環境変数の設定
ビルドのNode.jsは24.x(20は使えない)
Vercelで選べるNode.jsは24.x(既定)と22.xで、メジャー版だけを指定できます。Node.js 20は2026年4月30日のサポート終了を受けて2026年10月1日に新規デプロイで使えなくなり、20のままの関数があるプロジェクトは新しいデプロイでエラーになります。既存のデプロイはそのまま動きます。影響を受けるプロジェクトはvercel project ls --update-requiredで一覧できます。
版はプロジェクト設定のほか、package.jsonのenginesで固定でき、こちらが優先されます。">=22.0.0"と書くと24.xが選ばれるので、22.xに留めたいなら"22.x"と書きます。手元とVercelで版がずれるとビルド結果が変わるので、.nvmrcやCIの設定も同じメジャー版に揃えます。
{
"engines": {
"node": "24.x"
}
}
環境変数の接頭辞(VITE_とNEXT_PUBLIC_)
APIのURLやキーは、ダッシュボードのSettingsからEnvironment Variablesに、Production・Preview・Developmentの環境ごとに登録します。ブラウザ側のコードから読める変数は、ViteならVITE_、Next.jsならNEXT_PUBLIC_で始まるものだけです。接頭辞を付けた値はビルド時にJSへ埋め込まれ、誰でも読めるので、秘密の値には付けません。Vercelのシステム環境変数をViteから読むときもVITE_VERCEL_ENVのように接頭辞を付けます。値を変えたら再デプロイしないと反映されません。登録の手順とvercel env pullでの取り込みはVercelの環境変数の設定手順:Production・Previewの分け方とvercel env pull・Secret型【2026年10月】で解説しています。
公開範囲と独自ドメインの設定
プレビューURLでログインを求められる理由
プレビューURLを社外の人に送ると、相手にVercelのログイン画面が出ることがあります。2023年11月以降に作られた新規プロジェクトは、Deployment ProtectionのVercel Authenticationが既定で有効になっているためです。既定のStandard Protectionは、本番ドメイン以外のURL(プレビューと、デプロイごとに発行されるURL)を、チームのメンバーだけが見られるように保護します。社外の人に見せるときは、共有リンクを発行するか、アクセスの承認で相手を追加します。Hobbyで承認により追加できる外部ユーザーは1アカウントにつき1人です。
All Deploymentsによる本番URLの非公開化
公開前の本番URLも隠したい場合は、保護の範囲をAll Deploymentsに切り替えます。Deployment Protectionのドキュメントによると、本番を含む全URLの保護は全プランで使え、2026年9月9日からHobbyでも追加料金はかかりません。パスワードで保護するPassword ProtectionはProで保護するプロジェクトごとに月20ドルの有料機能で、Hobbyでは使えません。セキュリティ全般の設定はVercelハッキングの手口と対策|2026年4月の侵害と脆弱性・DDoS、安全性の確認も参照してください。
独自ドメインの割り当て
本番の.vercel.appに独自ドメインを付けるには、プロジェクトのSettingsのDomainsでドメインを追加し、表示されたAレコードかCNAMEをDNSに登録します。証明書は検証が通った後に自動で発行されます。レコードの選び方と、証明書が発行されないときの切り分けはVercelの独自ドメイン設定手順:Aレコード・CNAME・ネームサーバーの選び方とSSL発行待ちの対処【2026年10月】で扱っています。
よくある失敗と、Vercelを選ばないほうがよい場面
次の表は、症状ごとに最初に確認する項目です。それで直らないときは、デプロイのビルドログとブラウザの開発者ツールのコンソールで原因を絞ります。
| 症状 | まず疑う原因 | 直し方 |
|---|---|---|
| 下位ページの直リンクだけ404 | SPAのrewrites未設定 | vercel.jsonのrewrites |
| 画面が真っ白・APIに届かない | 環境変数の未登録・接頭辞なし | 登録後に再デプロイ |
| 手元では通るビルドが失敗 | Node.jsの版の違い | enginesで揃える |
| 相手にログイン画面が出る | Standard Protection | 共有リンク・承認 |
| 同じコミットで2回デプロイ | Git連携とActionsの併用 | deploymentEnabled: false |
| 試しのつもりが本番に出た | 新規プロジェクトの初回 | 空のページで初回を出す |
Hobbyでは仕事の案件を出せません。フェアユースのガイドラインはHobbyを非商用の個人利用に限っており、クライアントワークや社内業務のアプリはProかEnterpriseが前提です。Hobbyは同時に走るビルドが1件、1日に作れるデプロイが100件、1回のビルドは45分までなので、コミットの多いチーム開発ではすぐに待ちが出ます。料金の中身はVercel料金プラン|Hobby無料枠とPro($20)の中身・超過単価【2026年10月】で確認してください。
サーバー側の処理が多く、アクセスの山が大きいサービスは、関数の実行時間と転送量の従量課金が読みにくくなります。常時高い負荷で費用を固定したい、リージョンやネットワークを細かく制御したいという要件なら、コンテナ基盤のほうが向いています。逆に、ビルド済みのファイルを配るだけのVite製SPAで商用利用が無いなら、Cloudflare PagesやGitHub Pagesでも足ります。比較はVercelとCloudflare Pagesの違い:Next.jsの動かし方・料金の増え方・商用条件で選ぶ【2026年10月】にまとめています。
よくある質問
ReactアプリのVercelへのデプロイは無料でできますか?
Hobbyプランなら無料でデプロイできます。ただし対象は非商用の個人利用に限られ、業務やクライアントの案件はProかEnterpriseが必要です。
Vite製のReactとNext.jsでデプロイ方法は違いますか?
Git連携・CLIの手順は同じです。違うのはビルドの既定値(Viteの出力先はdist)と環境変数の接頭辞、そしてVite製のSPAで下位ページの直リンクが404になる点です。404はvercel.jsonのrewritesで全パスを/index.htmlへ向けて直します。Next.jsはこの設定が要りません。
npx vercel --prodは何をするコマンドですか?
Vercel CLIをグローバルに入れずに実行し、プロジェクトの本番ドメインへデプロイします。初回は対話でプロジェクトを紐づけ、ディレクトリに.vercel/project.jsonができます。新規プロジェクトの初回は--prodを付けなくても本番になります。
GitLabやBitbucketのリポジトリもデプロイできますか?
できます。GitHubと同じくリポジトリをimportすれば、ブランチへのpushでプレビュー、本番ブランチへのマージで本番がデプロイされます。CLIからデプロイしてブランチと結び付けたいときは、--meta gitlabDeployment=1 --meta gitlabCommitRef=ブランチ名のように指定します。
VercelでPWAを公開できますか?
できます。VercelはHTTPSを自動で付けるので、PWAに必要なHTTPSの条件は満たせます。インストールできるかどうかは、HTMLから参照したmanifestの中身(名前・アイコン・start_url・display)とService Workerの登録しだいで、ブラウザごとに条件も違うため、デプロイ後に実機のブラウザで確かめます。Viteならvite-plugin-pwaでmanifestとService Workerを生成します。SPAのrewritesを入れても、sw.jsやmanifest.webmanifestは実在するファイルとして先に返るので影響しません。