0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Supabase × Next.jsでログイン不要の簡易コメント機能を作ってみた 【学習記録】

Last updated at Posted at 2025-08-13

はじめに

こんにちは!
未経験からエンジニアを目指して学習中の hayate と申します。

初投稿の今回は、SupabaseとNext.jsを使って、
ログイン不要の簡易コメント機能
を作ってみました。

本記事で作るアプリはこんな感じです

スクリーンショット 2025-08-13 21.42.01.png

「フロントエンドとデータベースをどう繋げればいいのか?」
「Supabaseってどんなサービスなの?」
「ログインなしでDBにデータを保存できる?」

といった疑問を持っていた自分に向けて、
学んだこと・つまずいたこと・試したことをまとめておきます。


⚙️ 使用した技術スタック

  • Next.js
  • Supabase
  • JavaScript(React)

2. Supabaseのセットアップ

まずは、supabase上で以下の手順①〜③で実装します。
そうすることで、Next.jsアプリのひな型が作成されます。

🔧 ① プロジェクトの作成

  1. Supabase公式サイト にアクセスし、GitHubアカウントでログイン
  2. 「New Project」をクリックして、新規プロジェクトを作成
  3. プロジェクト名やパスワードを入力して進めます
  4. プロジェクト作成後、URLとanonキー(公開鍵)を控えておきます
     → この2つは後ほどNext.js側で使用します

🧱 ② テーブルの作成(コメント用)

  1. Supabaseの左メニュー「Table Editor」から「New Table」を選択
  2. テーブル名を comments に設定
  3. カラムは以下のように設定します:
カラム名 属性 備考
id UUID Primary key 自動生成
text Text 必須 コメント内容
created_at Timestamp Default: now() 投稿日時

Webアプリでデータベースを安全に操作するために、
まずRLS(Row Level Security)を理解しておきましょう。
Supabaseでは、デフォルトでRLSが有効になっており、ポリシーを設定しないと
どのユーザーからもアクセスできない状態になっています。

今回はあえてログイン不要で誰でもコメント投稿できる仕様にするため、
CRUD操作に対応したポリシーを順に設定していきます。
こんな感じ↓で設定します。

-- Create
create policy "Allow insert for all"
on public.comments
for insert
using (true);

-- Read
create policy "Allow read for all"
on public.comments
for select
using (true);

-- Update
create policy "Allow update for all"
on public.comments
for update
using (true);

-- Delete
create policy "Allow delete for all"
on public.comments
for delete
using (true);

🧪 C 書き込み用ポリシー+挿入テスト (Create)

ポリシーが設定できたら、実際にコメントを書き込めるか試してみます。
実際にコメントを書き込めるか試してみたあとの画像がこちら↓です

スクリーンショット 2025-08-09 22.21.00.png

✔️ R 読み取り用ポリシー(Read)

引き続き、次の工程でコメントテーブルに対して書き込み(Read)できるようにするポリシーを追加します。
SQL Editor上に入力した後のスクショ画像がこちら↓です

スクリーンショット 2025-08-08 21.42.29.png

✔️ U 更新用ポリシー(UPDATE)+更新テスト

今回は簡単なサンプルとして、誰でも更新可能にします。

以下のスクショ画像は「ERROR: 42710: policy "Allow all inserts" for table "messages" already exists」と既に設定していたので、エラーとなりましたが、以下の内容で設定しました。

スクリーンショット 2025-08-12 16.32.35.png

✔️D 削除用ポリシー(DELETE)+削除テスト

最後に、コメント削除のポリシーを作成します。

スクリーンショット 2025-08-12 16.52.37.png

「ERROR: 42710: policy "Allow delete for all" for table "comments" already exists」とUPDATEのフェーズのと同様に既に設定していたので、エラーとなりましたが、以下の内容で設定しました。

3. フロントエンド側から動作確認

では、ここからはVSCodeでフロントエンドのコードを書いていきます。
まずはフォルダー構図は以下の通りに構築します。

my-app/
├─ lib/
│   └─ supabaseClient.ts     # Supabaseクライアント
├─ pages/
│   ├─ index.tsx             # CRUDテスト画面
│   └─ _app.tsx
├─ components/
│   └─ MessageForm.tsx       # 新規投稿フォーム
│   └─ MessageList.tsx       # 一覧&更新削除
├─ .env.local                # 環境変数
├─ package.json
└─ README.md

3-1. Supabaseクライアントの作成

VSCodeを活用していくフェーズに入りまして、
lib/supabaseClient.jsと.env.localを作成します。

lib/supabaseClient.js
// lib/supabaseClient.js
import { createClient } from "@supabase/supabase-js";

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;

export const supabase = createClient(supabaseUrl, supabaseAnonKey);

上記のコードは、Supabaseへの接続設定を1か所にまとめて管理するために記述します。
毎回同じ初期化コードを書く手間を省き、再利用しやすくするのがメリットです。

.env.local
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL as string;
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY as string;

一方で.env.localファイルについては、プロジェクトごとの秘密情報(APIキーやURL)を
ソースコードに直接書かず、安全に管理するために記述します

3-2. 動作確認用ページの作成

VSCodeのメニューバーからターミナルをクリックし、
ターミナル画面が表示されたらbashモードに切り替えて、
入力コマンドに「npm run dev」と入力してサーバーを作動させます。

▲ Next.js 15.4.6 (Turbopack)
   - Local:        http://localhost:3000
   - Network:      http://192.168.0.200:3000
   - Environments: .env.local

この表示が見られたらOKで、「http://localhost:3000/crud-test」
のリンクにアクセス。
アクセスしてみると、このページへつながりました。

スクリーンショット 2025-08-13 18.50.20.png

3-3. フロントエンドの途中経過

CURDのテストを実行しようとしたところ、テキスト入力欄と追加ボタンしかないので、
CURDの全ての工程ができるようにデザインし直します。

スクリーンショット 2025-08-13 19.07.36.png

変更したポイントが次のとおりです。


✅ 修正ポイントまとめ

  • コメント一覧を取得して表示するように変更(Read)
  • コメント更新ボタンを追加、保存・キャンセルでUpdate可能に
  • コメント削除ボタンを追加してDelete可能に
  • 新規追加も引き続き利用可能(Create)

3-4. CRUD操作テスト

前述した内容と同じようにVSCodeのメニューバーからターミナルをクリックし、
ターミナル画面が表示されたらbashモードに切り替えて、
入力コマンドに「npm run dev」と入力してサーバーを作動させます。

前述した修正内容を踏まえて、再度CRUD操作テストを行います。
ここからCURD、Create / Read / Update / Delete の各処理を順にテストしていきます。
chatGPTの指示内容に忠実に進めてみました。
ということで初めはCreateの工程からです。

✔️Create

「newbie engineer」というレコードを新しくデータベースに保存する工程です。
「newbie engineer」と入力して、追加を押した後のsupabase上の画像です。

スクリーンショット 2025-08-13 20.59.21.png

DBに保存されたのを確認できたので、
CRUDのCの工程が成功しました。

✔️Read

続けて、Readの工程です。Createの工程で「newbie engineer」
と入力した後にこのままリロードしてみます
「newbie engineer」が一覧や詳細画面に表示されれば成功。

スクリーンショット 2025-08-13 21.11.16.png

Webに更新されたのを確認できたので、
CRUDのRの工程が成功しました。

✔️Update

続けて、一覧の「更新」ボタンを押してテキストを書き換えます。
Web画面とDBの両方から更新が確認できればOKです。
(「newbie engineer」を「junior engineer」に置換する工程です。)

スクリーンショット 2025-08-13 21.20.23.png

保存をクリックした後のWeb上の「junior engineer」に置換したのを確認。
そして、supabase上の「junior engineer」にtext欄に保存されていました。

スクリーンショット 2025-08-13 21.20.45.png

これで、「junior engineer」に置換ができたので、
CRUDのUの工程が成功しました。

✔️Delete

続けて、一覧の「更新」ボタンを押してテキストを書き換えます。
Web画面とDBの両方から削除が確認できればOKです。

スクリーンショット 2025-08-13 21.32.57.png

削除をクリックした後のWeb上の「junior engineer」がなくなったのを確認。
そして、supabase上の「junior engineer」にtext欄に削除されていました。

スクリーンショット 2025-08-13 21.36.06.png

「junior engineer」を削除できたので
CRUDのDの工程が成功しました。

4. 学んだこと・つまずいた点

学んだこと:
・supabaseからポリシーの設定をする方法
・VSCodeのターミナルから、「npm run dev」でサーバーを起動させてから、
 ブラウザでテスト画面にする方法

つまずいたこと:
・ポリシー設定がどこまでやったかの把握ができていなかった
・CURDのコード記述が中々うまくいかなかった
・フロントエンドの部分で、追加画面の表示のしかたに苦戦

5. まとめ

つまづいてしまった部分を記録し忘れるぐらい時間を費やしてしまいましたが、
簡単なコメント機能でも「DB連携+表示」が体験できて、とても勉強になりました。

もし同じように「Supabaseを触ってみたいけど、
何からやればいいかわからない…」という方の参考になれば幸いです!

次回は「React × useState × useEffectでAPIデータを表示してみた」
で記事を作成していきたいと思います。

最後まで読んでいただき、ありがとうございました。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?