【Supabase×Next.js】ブログにコメント機能をつけた時のハマりどころと学び
こんにちは、トシぼうです。
このブログにも、ついにコメント機能をつけました。
- 「せっかく記事を書いてるなら、感想や質問をもらえる場所を作りたい」
- 「でも WordPress みたいなガチのコメント欄はちょっと重い」
と思っていたので、今回はSupabase + Next.js(App Router)で、
「自分のブログにちょうどいい、シンプルなコメント機能」
を目指して実装してみました。
実際にやってみたら、
- テーブル設計
- RLS(Row Level Security)
- APIキーの扱い
- CSPエラー
など、いい感じにハマれるポイントがたくさんあったので、メモしておきます。
---
1. テーブル設計:最低限これだけあれば動く
コメント用のテーブルは、最終的にだいたいこんな感じにしました。
id:UUIDpost_slug:どの記事へのコメントかauthor_name:名前(ニックネーム)author_email:メールアドレス(非公開)author_ip:IPアドレス(スパム用の控え)content:コメント本文status:pending/approved/rejectedcreated_at/updated_at
ポイントは、
- 最初から公開しない情報(メール・IP)は別カラムに分けてお
- 表示には
post_slugとstatus = approvedだけを使う
というところです。
---
2. RLS(Row Level Security)で一回何も見えなくなる問題
Supabaseは、RLSをONにすると、何もポリシーを書かない限り一切データを返さなくなります。
最初はこれを知らずに、
1. テーブル作成
2. 適当にデータを入れる
3. フロントから読みに行く
4. 「あれ?approvedなのに全然表示されない」
という状態になりました。
# 解決した方法
コメントは全公開ではなく、「approvedだけ読める」ようにしたかったので、
- SELECT:
status = 'approved'だけ誰でも読める - INSERT:誰でも書けるが、中身は全部サーバー側でバリデーション
という感じでポリシーを設定しました。
---
3. APIキー問題:service_roleキーをフロントに出してはいけない
途中で一回、ブラウザの検証ツールから service_roleキーが見えてしまう事件がありました。
これは完全にやらかしで、
- 「環境変数に入れてるし大丈夫でしょ」と思っていた
- でも Next.js のクライアント側バンドルにも乗ってしまっていた
というパターンです。
# 学んだこと
- フロント(ブラウザ)からは必ず anonキーだけを使う
- service_roleキーを使いたい処理は、API Route or Server Actions側に寄せる
.envに書いてある=安全、ではない
という基本を、実践で痛感しました。
---
4. CSP(Content-Security-Policy)でSupabaseへの通信がブロックされる
コメントAPIまわりを実装して、ローカルでは普通に動いていたのに、
Vercelにデプロイしたらコメントが一切表示されない問題が発生しました。
ブラウザのコンソールを見てみると、
Refused to connect to https://xxx.supabase.co because it violates the following Content Security Policy...と出ていて、完全にCSPに引っかかっていました。
# 解決法
next.config.ts のヘッダー設定で、
connect-srcにhttps://*.supabase.coを追加- Prism.js のCDNを使っていたので、
script-srcとstyle-srcにhttps://cdnjs.cloudflare.comも追加
を行いました。
これで、ようやく本番環境でもコメント一覧が表示されるように。
---
5. スパム対策:完璧は無理なので「コスパのいい対策」を積む
コメント欄を開くと必ず出てくるのがスパム問題です。
- 宣伝リンクだけ貼られたコメント
- 機械的に連投されるコメント
など。
今回は、
- 簡単なNGワードチェック
- URLの数が多すぎるコメントは弾く
- 一定時間内の連投を制限するレートリミット
くらいの、「軽いけど効くライン」で実装しました。
将来的にスパムが増えてきたら、reCAPTCHA や Akismet 的なソリューションも検討するつもりです。
---
6. 実装してみて感じたこと
- コメント機能は「付けた瞬間から価値が出る」わけではない
- それでも、読者が声を出せる場所があるというのは大きい
- Supabaseは、ちゃんと設計すれば個人ブログレベルには十分すぎるパワーがある
特に、RLSやCSPまわりで、
「セキュリティって、フレームワークに任せきりじゃなくて、自分でちゃんと理解しておく必要があるな」
と強く感じました。
---
おわりに
今回のコメント機能実装で得られた学びをざっくりまとめると、
- SupabaseのRLSは、ONにするだけじゃなくポリシー設計が本番
- APIキーは「どこから見えるか」を常に意識する(特にservice_role)
- CSPは便利だけど、外部サービスを使うならちゃんと例外を許可する必要がある
- スパム対策は「いきなり完璧を目指さず、コスパのいいところから」
という感じでした。
これからコメント機能をつけてみたい人や、「Supabase気になってるけど何からやろう」という人の、
一つの参考になればうれしいです。

