フロントエンド初心者がストーリー(ぽいもの)を投稿できるSNSサイトを作った【Firebase, React, Next.js, Twemoji】

#はじめに
去年に大学の学園祭ウェブサイトをRailsで作ってからウェブに興味を持ったので、何か面白いウェブアプリを作ってみたいと思い、３ヶ月かけウェブアプリを企画開発してみました。
SNSという形にしたのは、コンテンツをユーザーが増やしてくれる点や投稿のシェアによるサイト流入が見込める点、シンプルに自分が暇つぶしにみれるサイトが増えればいいなと思っていたためです。現状広告等無いですがあわよくば小遣い稼ぎをば、という思いもあります（笑）。

本記事では、主に実装面について技術選定や感想について述べます。

#作ったもの
wbbow - 絵文字で簡単ストーリー
https://wbbow.com

> **wbbow**
wbbowは絵文字とテキストでストーリーライクな投稿を匿名で投稿できるウェブサイトです

#wbbowとは？
絵文字とテキストのみとシンプルな作りで、インスタでよく見るストーリーズの簡易版のような投稿ができるサービスです。ちなみに一応読み方はウィボーです。
特徴としては、

* 匿名
* ログインなし
* いいねは無限に押せる
* 絵文字はsvgのため拡大しても綺麗
* 投稿には投稿でリプライでき、リプライ場所も自由に設定できる

などです。発想としては、インスタ(ストーリーズ)+ツイッター(短文投稿)+はてな匿名ダイアリー(匿名性)を組み合わせたものです。ログインやユーザーの概念が無く匿名なのは、一番は実装が簡単になるからですが、利用登録などの初期ハードルをなくしたり、より気軽に、普段の自分に縛られず使って欲しいという理由もあります（余裕があれば、今後ユーザー登録を可能にするかも）。また、テキストと絵文字だけなのは、画像等も可能にするのがコストや実装面のハードルが高いのもありますが、不適切な画像等の削除などが個人では対応できない可能性が高いと判断したためです。個人的にはテキストと絵文字だけというのが、むしろクリエイティビティを刺激するのではとも感じています。
![ホーム](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784893/f1774737-da9a-0b8b-fd9d-61e82e72ab4d.png)

各投稿は無限の広さのキャンバスの中心に配置され、その周りに自由にリプライを投稿することができます。
![各投稿](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784893/aeca2814-9d29-0e32-e815-d86cc91330fa.png)

テキストと絵文字、リプライの場所などを工夫することで様々な使い方ができる新しい形のSNSです。

#使用サービス・ツール
フロントエンド：React, Next.js
データベース：Firebase Realtime Database, Cloud Functions
ホスティング：Vercel, Github Pages(サポートページ)
ソース管理：Github
アクセス解析：Google Analytics, Firebase Analytics
SEO対策：Google Search Console
絵文字：Twemoji

以下それぞれについて感想です

##フロントエンド - React, Next.js
フレームワークは、サーバーレスなものを使用したいと思い、SPAを実現できるReact, Vue, Angularなどから選びました。JavaScriptベースで書いてみたかったのと、処理速度が少し早いようだったのでReactを選択しました。Next.jsはReact使用時のデファクトスタンダードかと感じ、使用しました。結果的にVercel(Next.jsも作ってる)へのデプロイがすんなりできたので、満足しています。

##データベース - Firebase
とりあえずFirebase使っておけば間違い無いだろうと。Realtime Database と Cloud Firestoreで迷いましたが、色々調べデータ構造が単純なことやFirebaseのページでもRealtime Databaseを推されたことなどからRealtime Databaseを選択しました。が、今後機能を追加することでデータ構造が複雑化したり、Firestoreの方が開発されていることを考えると、もう少し熟考する必要があったかなと思います。

##ホスティング - Vercel
現状完全に静的ファイルのみ&SSRなしのサイトなのでNetlify, Github Pages, Cloudflare Pages, Firebase Hostingなど候補は複数ありましたが、最終的にはVercelに落ち着きました。以下それぞれ試した総評です。
###Netlify
無料枠はそれなりですが、国内だと少し速度が遅いようです。
###Github Pages
唯一読みこんだページでJavaScriptが機能しませんでした。そのためウェブアプリでは使っていませんが、サポートページ(https://support.wbbow.com )ではGithub Pagesを利用しています。
###Cloudflare Pages
静的ホスティングでは新参者ですが、容量の制限もなく日本でもCDNの恩恵もかなり与れます。当初これで行こうと思っていましたが、ダイナミックルーティングを使用しているページに初回アクセスした場合、404エラーになるため、残念ながら見送りました。また、発展途上のためウェブコンソールのバグもみられました。(cloudflare workers というツールを利用すればいけそうが、ここに時間を使いたくなかったので今回は使っていません)
###Firebase Hosting
データベースと同じプラットフォームで管理できますが、無料枠制限が他より厳しいです。
###Vercel:crown:
無料枠制限が緩く、Next.jsとの親和性も高いです。他のサービスでは確認していませんが、リダイレクトや環境変数もウェブコンソールで設定できたのは楽でした。
ただ、広告をつけることを考えているので、無料枠が非営利目的に限るのが引っかかります。(個人ブログの広告掲載はOKらしいですが、wbbowの場合どうなんだろう？)

##絵文字 - Twemoji
[Twemoji](https://twemoji.twitter.com)はTwitterのオープンソース絵文字です。ツイートする時の絵文字はだいたいTwemojiになっています(ちなみにQiitaのMarkdown絵文字もTwemoji:smile:)。グラフィックは CC BY 4.0 の元、自由に使うことができます。AppleやGoogleの絵文字は著作権の問題等で、そのままサービス内で使うのはかなりグレーですが、Twemojiは堂々と使うことができます！さらに素晴らしいのはsvgに対応していることです。wbbowでは各投稿を自由に拡大縮小して見られるのでsvgが使えるのはありがたいことです。絵文字が綺麗に見えるだけでなく、デバイス間のグラフィックの統一も図ることができています。また、テキスト内の絵文字もTwemojiに変換してくれるJavaScriptライブラリが用意されており非常に助けられました。
Twemojiがなければ、wbbowが完成することはなかったと言っても過言ではないです。
(こんだけ言っといてあれですが、読み方がいまいちわかりません。トゥエモジでいいんですかね？)

#セキュリティ
###Firebase Realtime Database
できるだけ厳しくセキュリティルールを定めています。

###テキストのサニタイジング
XSS対策として。

###テキスト内リンクのrel
テキスト内のURLに対して自動でリンク化するのですが、その際aタグにrel="noopener noreferrer"オプションを追加し遷移先の脅威の影響を最小化しています。

その他にも投稿時のバリデーションなどで対策をしています

#課題点・展望
### OGP・SEO周り
この辺を充実させるにはSSRがほぼ必須のようですが、これだけのためにSSR使うか…？となって静的にできる範囲内になっています。ホスティングをVercelにしたことでSSRも簡単にできそうなので今後対応するかもしれません。投稿のOGP画像を生成できたりするとさらにサイト流入を促せるかもですね。

###パフォーマンス周り
現状ページ読み込み速度は遅くはないのですが、速くもないので遅延読み込みは組み込みたいところです。
また、最初のFirebase接続に時間がかかっているのか、肝心の投稿一覧の表示に時間がかかります。この辺に関する情報が少ないのですが、何か対策があれば教えていただきたいです。

###編集機能の充実化
整列(アライン)機能やテキストの左右揃えなども組み込もうと考えていましたが、初期バージョンでは見送っているので今後追加したいです。
また、スマホからの利用をメインで考えているため、ショートカットなどが軒並み使えません。元に戻すやコピーなどはあった方がUX的にも満足度は高いとは思っています(が、中々実装ハードルが高い…)。


#雑感
タイトルにはフロントエンド初心者と書いていますが、作り始めはJavaScriptも怪しいレベルだったので、かなり苦労しました。またウェブ開発あるあるですが、ブラウザ・デバイス間の挙動の違いも大変でした。特に大変だったのは、svgのforeignObjectの扱いです。wbbow内では多用するのですが、ブラウザ間差異が大きかったり、バグっぽい動作をしたりと試行錯誤を繰り返さざるをえませんでした。
思い返せば全部めんどくさいなあと思いながら作ってたような気もしますが、やっぱりうまく動いた時の喜びはひとしおでしたね。今回のプロジェクトを通してReactやFirebaseはじめフロントエンドの魅力や奥深さを楽しむことができました。あとはこのサービスを1人でも多くの人に楽しんでもらえたらと願うのみです:pray:

#最後に
[wbbow.com](https://wbbow.com)
なにはともあれぜひ何か投稿してみてください！非常に喜びます！
投稿やサイトをシェアしていただけるとさらに感謝します！！！！
また、アドバイスもございましたらいただけると幸いです。

拙文をお読みいただきありがとうございました。