VercelとSupabaseでSNS運用ツールをデプロイした話 – 初心者が躓いたポイントと解決法

こんにちは!プログラミング学習中のゆうちです。
今日は、自作のSNS運用ツールをVercelにデプロイして、Supabaseでデータベースを永続化するまでの道のりをまとめてみました。
とはいっても、正直9割9分ClaudeCodeにやってもらったものです・・・。私は、ときどき「YES」とEnterキーを押すくらい。
しかし、初心者でもAIを活用すればツール開発ができることがわかったので、その記録として残します。
このブログの内容もAIを活用して書いています。なので正直、自分で発信していてわからない用語ばかりです。でも、より正確な情報の方が読んだ方のためになるとも思っています。
表現が少し白々しいのはご愛敬で、でも、ClaudeCodeを活用しても苦労したことは本当です。
作ったもの
SNSの投稿を一元管理できるツールを作りました。主な機能は:
- 複数SNS(Twitter、Instagram、Facebook)の投稿管理
- 投稿の作成・編集・削除
- エンゲージメント分析ダッシュボード
- 投稿パフォーマンスの可視化
最初はローカルのSQLiteで動かしていましたが、本番環境ではデータが消えてしまうという問題があったので、Supabaseを使うことにしました。
躓いたポイント1:TypeScriptの型エラー地獄
まず最初に直面したのが、TypeScriptの型エラーの嵐でした。
Error: Unexpected any. Specify a different type. @typescript-eslint/no-explicit-any
このエラーが大量に出て、ビルドが通らない…。
解決方法
APIルートで使っていたany
型を、きちんと型定義することで解決しました:
// Before
const params: any[] = [];
// After
const params: (string | number)[] = [];
また、データベースから取得するデータにも型を定義:
interface Post {
id: string;
platform: string;
content: string;
likes_count: number;
// ... 他のプロパティ
}
const posts = db.prepare(query).all(...params) as Post[];
型定義は面倒に感じるかもしれませんが、後々のバグを防ぐためにも重要だと学びました。
躓いたポイント2:useCallbackの依存配列問題
React Hooksの使い方でもエラーが出ました:
Type error: Block-scoped variable 'fetchAnalytics' used before its declaration.
関数を定義する前に使おうとしていたのが原因でした。
解決方法
useCallback
を使って関数をメモ化することで解決:
import { useCallback } from 'react';
const fetchAnalytics = useCallback(async () => {
// データ取得処理
}, [selectedPlatform, dateRange]);
useEffect(() => {
fetchAnalytics();
}, [fetchAnalytics]);
React Hooksのルールは最初は複雑に感じましたが、パフォーマンスと保守性のために重要なんですね。
躓いたポイント3:Next.js 15の新しいAPI仕様
Next.js 15では、APIルートのパラメータの扱い方が変わっていました:
// Next.js 14以前
export async function PUT(request: NextRequest, { params }: { params: { id: string } }) {
const { id } = params;
}
// Next.js 15
export async function PUT(request: NextRequest, context: { params: Promise<{ id: string }> }) {
const params = await context.params;
const { id } = params;
}
params
がPromise
になっているので、await
が必要になりました。これに気づくまで時間がかかりました…。
躓いたポイント4:Vercelでのビルドエラー
ローカルでは動くのに、Vercelでビルドエラーが出る現象に悩まされました。
原因と解決
- 環境変数の設定忘れ
- Vercelのダッシュボードで環境変数を設定する必要がありました
- ポート番号の勘違い
- ローカルでは3000番ポートで動いているのに、3001番にアクセスしていました
- プロジェクト構造の問題
package.json
がサブディレクトリにあったため、正しいディレクトリからデプロイする必要がありました
Supabaseとの連携
SQLiteからSupabaseへの移行は思ったよりスムーズでした:
- Supabaseでプロジェクトを作成
- スキーマを設定(SQLを実行)
- 環境変数を設定
- クライアントコードを修正
// SQLiteの場合
import Database from 'better-sqlite3';
const db = new Database('posts.db');
// Supabaseの場合
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(supabaseUrl, supabaseAnonKey);
学んだこと
- エラーメッセージは友達
- 最初は怖かったエラーメッセージも、よく読めば解決のヒントが書いてある
- 型定義の重要性
- TypeScriptの型定義は面倒だけど、バグを防ぐ強力な味方
- 公式ドキュメントの大切さ
- Next.js 15の変更点も、公式ドキュメントにちゃんと書いてありました
- 一歩ずつ進む
- 複雑な問題も、一つずつ解決していけば必ずゴールに辿り着ける
一番の収穫は、ClaudeCodeを活用すれば初心者でもなんとかツールが開発できそうだということです。
SupabaseとVercelが今回使えるようになったのはとてもうれしいです。
やはり、ツールを作りながら学ぶ方が学習速度が速くなると思います。逆に、積み上げでやっていくとなると、途方もなく時間がかかってしまうなと今回も感じました。
AIを活用しながらも、そのコードを少しずつでも理解しながら進めることが重要だと思って勉強を続けたいです。
完成したアプリ
最終的に、以下のURLでデプロイできました:
https://sns-operation-tool-nextjs.vercel.app
データも永続化されて、実用的なツールになりました!
まとめ
エラーとの格闘は大変でしたが、一つ一つ解決していく過程で多くのことを学べました。特に、TypeScriptとNext.js 15の新機能について理解が深まったのは大きな収穫です。
次は、このツールに自動投稿機能やAIを使った投稿文の生成機能を追加してみたいと思っています。
同じようにVercelデプロイで悩んでいる方の参考になれば嬉しいです。質問があれば、コメントいただけたら嬉しいです。一緒に学んでいきましょう⭐