前回の記事はこちら:
はじめに
前回の記事「Chromebookとスマホだけで冷蔵庫管理アプリを作ってみる -構想編-」では、思いついた構想と「まずこの流れでやってみます」という計画をご紹介しました。
今回はその実践編として、実際にGitHub・Vercel・Supabase・Gemini APIを繋いでいった結果と、その過程でハマったポイント・乗り越え方をまとめます。
この記事はこんな方におすすめ
- 前回記事を読んでくれた方
- 重い開発機がなくてもアプリ開発ができるのか気になっている方
- GitHub Codespaces、Vercel、Supabaseを個人開発で組み合わせたい方
- Gemini APIを使い始めたばかりの方
- 「環境構築で心が折れそう」な経験がある方
実際に作ったもの
前回立てた計画どおり、次の4つを実装しました。
- ① 環境構築:Chromebookとスマホだけで、GitHub Codespaces上にNext.jsの開発環境を作り、Vercelに自動デプロイされる状態にした
- ② レシート解析API:Gemini APIに画像を送り、商品名・カテゴリ・金額・即食/保管の分類をJSONで返すAPI Routeを実装した
-
③ データベース保存:Supabaseに
productsテーブルを作成し、Geminiの解析結果をそのまま保存する処理を実装した - ④ エラーハンドリング:Gemini APIの混雑エラー(503)が出たときに、利用者に分かりやすいメッセージを表示するようにした
スマホのカメラでレシートを撮影 → 自動でGeminiに送信 → 結果を画面に表示 → Supabaseに保存、という一連の流れを実機で動作確認できました。「レシートを1枚撮るだけ」の入力ゼロ化が、ひとまず一番シンプルな形で実現できたことになります。
ここまでで実感しているのは、重い開発機がなくても個人開発自体は思ったよりハードルが低いということです。詰まるポイントは大体「どのボタンを押せばいいか分からない」という、UI探しの部分でした。
余談ですが、今回の開発では初めてClaudeを使ってみました。スクショを見せながら「次どうすればいい?」と聞くだけでサクサク進んでいったのが正直かなり驚きでした。
今回の開発スタイル:スクショ駆動開発
普通、この手の記事は「ターミナルでこう打って〜」で完結するのですが、今回はCLI自体は多少分かるものの、画面が英語だらけで用語や表示に戸惑う場面が多いところからのスタートでした。
そこで採用したのが、**「今の画面をスクショで撮って、それをAIに見せながら『次に何を押せばいいか』を一つずつ教えてもらう」**という進め方です。
- 画面のどこが分からないか、を言葉で説明する必要がない(スクショを見せれば一発で伝わる)
- AI側も「その画面ならこのボタンです」と的確に案内してくれる
- エラーが起きても、エラーメッセージごとスクショを見せれば原因の切り分けが早い
「コードが書けないから開発は無理」ではなく、「画面を見せながら一歩ずつ確認する」だけでも、環境構築レベルなら十分に進められるというのが今回の一番の発見でした。
ハマりポイント集
環境構築編
create-next-appとREADME.mdの衝突
リポジトリ作成時に「Add a README file」にチェックを入れてリポジトリを作ったところ、npx create-next-app@latest . を実行してもファイルが1つも増えない、という謎の状態にハマりました。
原因は、create-next-appが「ディレクトリ内に既にファイル(README.md)がある」ことを検知して、確認プロンプトを出さずに黙って処理を止めていたことでした。
rm README.md
npx create-next-app@latest .
README.mdを一度消してから実行し直すことで解決。地味に「エラーメッセージすら出ずに黙って失敗する」パターンが一番厄介でした。
認証編
Vercelの「気づいたらProプラン」トラップ
Vercelのオンボーディング画面で最初から「I'm working on commercial projects(Pro)」が選択された状態になっており、そのまま進むとProプランのトライアルが開始されるところでした。個人開発なら「I'm working on personal projects(Hobby)」を必ず選び直す必要があります。海外サービスのオンボーディングは有料プランがデフォルトになっていることがあるので要注意です。
GitHub×Vercel連携で30分格闘した話
VercelでリポジトリをImportしようとしても一覧に何も出てこない、という状態に長時間ハマりました。原因を辿ると、
- VercelにGitHub Appがそもそもインストールされていなかった(
github.com/settings/installationsで確認できる) - インストールしようとすると、GitHub側の「sudo mode」(機密操作の前に求められる本人確認)に阻まれる
- メール認証を挟んでようやくインストール画面にたどり着く
という多段階の壁でした。「連携ボタンを押したのに反応がない」時は、大抵このどこかで詰まっています。焦らず一段ずつ確認するのがコツでした。
APIキー編
.env.localはローカル専用、本番には別途登録が必要
Gemini APIキーもSupabaseの接続情報も、ローカルの.env.localに書いただけではVercel上の本番環境には反映されません(そもそもGitHubにも送られない設計です)。そもそもこの仕組み自体を知らず、「ローカルでは動くはずなのに本番でエラーになる」を2回繰り返しました。
Vercelの「Environment Variables」に同じキーを登録し、その後再デプロイ(Redeploy)しないと反映されないという点も合わせて注意が必要です。
Supabaseのキー名がドキュメントと食い違う
コード側では慣例的にNEXT_PUBLIC_SUPABASE_ANON_KEYという名前を使ったのですが、Supabaseの接続画面から発行された変数名はPUBLISHABLE_KEYという別名になっていました。ビルドログに
Error: supabaseKey is required.
と出てハマりましたが、原因は単純に変数名の不一致でした。Supabase側の案内どおりの名前をコピーするか、コード側の変数名をそれに合わせるかのどちらかで解決します。
Row Level Security(RLS)の確認ダイアログ
Supabaseでテーブルを作成する際、デフォルトで「Enable Row Level Security」にチェックが入っています。個人開発フェーズではポリシー未設定のままだとデータが一切取得できなくなるため、開発中はオフにして進めました。ただしオフにすると「誰でも読み書きできる状態」になるので、接続情報をQiitaやGitHubに載せる前には必ずオンに戻し、ポリシーを設定する必要があります。ここは公開前のチェックリストに入れておこうと思います。
Gemini APIとの付き合い方:無料枠は普通に混む
コードもキーも正しく設定した後、最後にぶつかったのがこれです。
Error [ApiError]: {"error":{"code":503,"message":"This model is currently experiencing high demand...","status":"UNAVAILABLE"}}
503 UNAVAILABLEは「モデルが混雑しているので時間を置いてください」という意味で、コードの不具合ではありません。無料枠のモデルは時間帯によって普通に混雑するので、慌てずに5〜10分待って再試行するのが一番確実でした。待っている間にこの記事を書いていた、というのが実情です。
とはいえ、素のError [ApiError]がそのまま画面に出ても不親切なので、API Route側でステータスコードを見て、503の時だけ利用者向けのメッセージに変換するようにしました。
} catch (error: any) {
console.error(error);
if (error?.status === 503) {
return NextResponse.json(
{ error: "Geminiが混み合っています。5分ほど待ってからもう一度お試しください。" },
{ status: 503 }
);
}
return NextResponse.json({ error: "解析に失敗しました" }, { status: 500 });
}
実際に混雑タイミングで試したところ、ちゃんと「5分ほど待ってからもう一度お試しください」と表示されることを確認できました。エラーメッセージ一つでも、原因が分かる文言にしておくだけで無駄な混乱を減らせます。
おまけ:Claudeの利用制限に引っかかって課金した話
今回スクショを見せながらのやり取りをずっとClaudeにお願いしていたのですが、開発が長丁場になった結果、無料枠の利用制限に引っかかってしまいました。せっかく積み上がった会話の流れを途切れさせたくなかったので、そのまま有料プランに課金して続行しました。スクショ駆動開発は便利な反面、やり取りの往復回数が普通のコーディングより多くなりがちなので、この点は事前に頭に入れておくとよさそうです。
まとめ
今回、重い開発機を使わずChromebookとスマホだけで、GitHub Codespaces・Vercel・Supabase・Gemini APIを一通り繋ぐところまで進められました。詰まったポイントを振り返ると、コードの難しさよりも「どのボタンを押せばいいか分からない」「エラーメッセージの意味が分からない」というUIと用語の壁がほとんどでした。
裏を返せば、画面をスクショで見せながら一つずつ確認していく進め方さえあれば、環境構築のハードルは思ったより低いということでもあります。「コードが書けないから」と諦めている方にも、この進め方は選択肢になるのではと思います。
次回はPhase 2、保管食材と即食食材を分けたダッシュボードUIの実装編を書く予定です。
続きはこちら: