Supabase の力を借りて非エンジニアが Web サービスを個人開発しました【Next.js(App Router),Vercel,Supabase】

## はじめに

はじめまして。
フリーランスとして Web デザイナーを営んでいるものです。
この度、「一発当てて FIRE」を目指して個人開発の Web サービス([monolink | モノリンク](https://monolink.me))をリリースしました。<br>

https://monolink.me

個人開発とは言え Copilot さんにはだいぶお世話になったので、一人で開発と言うのは少しばかり憚られます。さらにバックエンドはBaasのSupabaseにほぼすべて任せてます。
ありがとう Copilot & Supabase🙇🏻

## 自己紹介

<dl>
  <dt>年齢</dt>
  <dd>38歳</dd>
  <dt>職歴</dt>
  <dd>
  ・アパレル販売員 7年<br>
  ・グラフィック系企業のWebデザイナー 3年<br>
  ・フリーランスのWebデザイナー 6年<br>
  </dd>
  <dt>普段の仕事内容</dt>
  <dd>Web デザイン,コーディング,WordPress テーマ制作</dd>
</dl>

普段は WordPress でコーポレートサイトの制作をデザイン〜構築まで行うことが多いです。
React は 2,3 件小さなコンテンツ制作の経験がありました。Astro だったり Three.js だったりフロントエンドを広く浅〜く泳いでます。
そのためサーバー周りやバックエンドに関しては知識が乏しいです。インフラ？なんそれ状態です。

## サービス内容

本サービスは、主にネットショップ出品者に向けた Web サービスです。
Amazon や楽天など同じ商品を複数のサイトで出品していると、SNS での告知やお客さんに URL を伝える際に冗長になってしまいます。
そのような場合、モノリンクを使うと便利です。商品ごとにリンクを 1 ページにまとめられるので簡潔に伝えられます。

紹介者や人気商品を分析するために、アクセスやクリック数などを計測できる機能もつけました。

## 開発のきっかけ

アパレル販売員をしてた頃にちょうど ZOZOTOWN が躍進してきました。
個人売で成績評価されるので、接客したお客さんにはネットではなく店頭で買ってもらいたいというのが正直なところ。
辞めてから考えるとすごく自己中心的な接客だったなと反省しました。そこで、お客さんに商品の販売 URL を手軽に伝える方法があれば良かったなと考えたのがきっかけでした。できればそこに誰が接客したが分析できる機能がついていればなお良し。

一方、各種 AI サービスが勢いを増す中で今まとめサイトってのはちょっとシンプル過ぎやしないか、との懸念もありました。
ただ、Linktree や lit.link などのプロフィールサイトをあえて使う人が多いことを鑑みるに、今求められているものって時代を逆行してもシンプル&必要最低限の機能ってこともあるのではないかと勝手に憶測&ポジティブシンキングで解決しました。してない？

また、単純に一消費者として、提供者側にしてもらいたいサービスだったからです。
特にふるさと納税返礼品は、その自治体や事業者のファンの人へ、ポータルサイト側でなく、自治体・事業者側からの発信をもっとスマートにしてくれたらなと常々考えてました。

## 主要な技術スタック

#### フロントエンド

- Next.js (App Router + Pages Router) 14.1.2
- TypeScript v5.3.3
- React Hook Form v7.50.1
- Radix UI
- Nextra v2.13.4
- Google APIs v133.0.0

#### バックエンド

- Supabase
- Vercel
- CloudFlare (ドメイン)
- さくら (メールサーバー)

### システム構成
![システム構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144156/62ed1aab-163f-eab2-30e1-62b39c5f7890.png)



### 技術選定理由

#### Next.js

もともと React は趣味程度で触ったり、小規模なコンテンツ制作の経験はあったので Next.js にしました。
制作開始が 2024 年初頭ということもあり、新しい技術である App Router をメインに採用しました。
ドキュメントページには Nextra を使ったのですが、まだ App Router には対応しておらず、そこだけ Pages Router にしてます。
ちなみにスタイリングは CSS Modules(SCSS)です。Tailwind を使いたかったのですが、デザイナー・コーダーの経験があるとどうしても使いづらくて。私だけ？

#### Vercel

単純に Next.js と相性が良い、デプロイ時にエラーが少なそうという理由でホスティング先として選びました。また、Serverless Functions が使える点も大きかったです。今回 Serverless Functions では指定 URL から OGP の取得と、OGP 画像をバイナリーデータとして変換させること、Google Analytics Data API からのデータ取得などを行っています。

#### Supabase

バックエンドに関しては知識が乏しいためなるべく簡単に使えるという点に重きを置き、2024 年現在もっとも勢いのある BaaS である Supabase を選びました。DB も認証もストレージも全部任せてます。<br>
あと Supabase のエンジニアで X などで情報発信しているタイラーさんの X レス率が高かったのも信頼できたポイントです。

## 主な機能

- 認証系
  - ログイン/Google ログイン
  - ログアウト
  - 新規登録/Google 登録
  - 認証メール
  - メアド変更
  - パスワードリセット/変更
  - アカウント削除
- アイテム情報
  - 新規登録/削除
  - 並び替え
  - URL 情報からファビコン取得
  - URL 情報から OGP 画像取得
  - カテゴリ登録/削除
  - サービスアイコン登録/削除
  - QR コード発行
- アカウント情報
  - プロフィール等編集
  - アバター画像登録/削除
- アクセス分析
  - 分析用タグ登録/削除
  - アクセス情報を Google Analytics Data API (GA4) から取得

## 画面紹介

### 管理側

#### 会員登録画面
![登録画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144156/032d382a-e5c3-6cd7-6cdd-32e6360d977c.png)
シンプルなフォームをモーダルコンポーネントで作ってます。ログインフォームも同様です。

#### アイテム一覧画面
![アイテム一覧.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144156/14020eba-995d-2d70-755a-6132dcf76b22.png)
検索やフィルター機能もつけました。アイテムの並び替えは dnd Kit を使って実現しています。

#### アイテム新規登録/編集画面
![アイテム編集.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144156/33d931e5-fb41-6edd-5d58-97f1a9697d42.gif)
アイテム画像の自動取り込み機能をつけました。

#### アカウント情報画面
![アカウント編集.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144156/45c70c51-9914-f0e7-dd82-6f9a92674f06.gif)

#### 設定画面
![設定.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144156/3016967e-751a-0472-02df-997c57db6ad5.gif)

#### アクセス分析画面
![アクセス分析.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144156/2fcca8f5-b999-05e6-30d7-b23caadbf72c.gif)
Google Analytics Data API で取得した結果を Chart.js でグラフ化してます。

### フロント側
![front.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144156/e5affda3-f7da-d8ff-6e57-a2a014e8f64e.png)


## はまった箇所

#### DNS レコード

やはりバックエンドの知識が乏しく DNS レコードに関しては四苦八苦しました。
特に Gmail が DKIM 対応していないと迷惑メール判定にするよ、と言うタイミングだったので。。。
ドメインを CloudFlare、メールサーバーをさくら、に分けたのも良くなかったかも。さくら一本なら簡単だったかと。
知識のある方が見たら一瞬なのでしょうけど、もっと勉強します！
ちなみに SendGrid も候補に入れていたのですが、個人事業主は対象外らしいので使えませんでした。

#### Google Analytics Data API (GA4)

API の取得方法が複雑過ぎてなかなか理解できなかったです。
GA4 になって間もないので API の新しい情報がまだ少ないのも原因でしょう。<br>今回いろいろな箇所を Github Copilot に課金して教えてもらってはいたのですが、なかなか Copilot でも的確なクエリは出せませんでした。

#### WebView 内での Google OAuth

Instagram へ広告を出したのですが、Google OAuth がエラーになってしまいました。
どうやら Google OAuth は、ポリシーによって、Web View(ネイティブアプリの内部ブラウザ)では機能しないとのこと。
こちらの記事が参考になりました。

https://zenn.dev/aiq_dev/articles/ea6d562ae0ff5e

## リリースして 1 ヶ月が経過

で、リリースして 1 ヶ月が経ちサービスへの反応はどうかと言うと、なかなか厳しい状況です。
リリースしてすぐに数名から嬉しい反応がいただけたのでそれを糧にして頑張っています。
Google や X、Instagram に少しずつ広告も出しているのですがなかなか会員登録までは繋がらず。
FIRE への道のりは遠そうです。
今後はサービスの機能面ではなく、集客面を試行錯誤していこうと思っております。

## 終わりに

この記事を読んでいただき、ありがとうございました。
BaaS の Supabase が私に足りない技術をフォローする形で、非エンジニアでも一人で Web サービスのリリースまでは出来ました。
私の経験が何かの参考になれば幸いです。
これからも「モノリンク」の開発を続け、より良いサービスを提供できるよう努力していきます。
皆様のご支援とご鞭撻を心よりお待ちしております。