Next.js13とsupabaseで新世代タイピングゲームを作成したので，内容を紹介します．

## 追記(7/11)

記事の続編を書きました！
ぜひ読んでレビューをくださると幸いです．

https://qiita.com/y4asse/items/7873d7f2d341cc431060

# はじめに
フロントエンドにNext.js，バックエンドはsupabaseを利用してGPTが毎回テキストを作ってくれるタイピングゲームを作成しました．2カ月前にJSの基礎のところから独学で勉強をスタートして，初めて作ったwebアプリケーションなので，まだまだ改善点が多いと思っています．ホスティングはvercelを利用しました．

# アプリの概要
git↓

https://github.com/y4asse/ai-typing-next-supabase

アプリ↓

https://ai-typing.app

アプリ名：AI Typing
![スクリーンショット 2023-05-16 110705.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3162990/ec2300ac-eaa1-8356-4b9c-626c28a104d7.png)

ゲームをスタートするとGPTが毎回テキストを作ってくれるタイピングゲームです．

# 作成理由
将来，今までにない新しいサービスを開発したいと思っているので，これまでにないようなアプリを作りたいと考えました．何を作ろうかと考えた時，ちょうどOpenAIのAPIが公開されたので，AIを使った今までにないアプリを作ろうと思いました．いろいろ候補が上がっていたのですが，技術的な面や市場調査を行った結果今回のアプリを作成することにしました．
従来のタイピングゲームは決まった文章しか出ないので文章の内容に新鮮さがないなと思っていました．なのでAIを使えば毎回違う文章を作って新鮮なゲーム体験をできるのではないか！と考えました．

# 使用技術
・Typescript
・React
・Next.js
・Redux
・Supabase
・Open AI API

# 機能一覧
・ランキング機能
トップ10の順位を見れます
だれでも使える

・コメント機能
ランキングのコメント欄に投稿することができます
編集，削除可能
ログインユーザのみ

・git Oauthログイン認証
gitのアカウントを利用して，簡単にログインすることができます．

# 技術選定
### typescript , react
フロントエンドではTypescript以外ないので，それに付随してライブラリを考えました．react, vue, angularで悩みましたが，利用者が多く，ライブラリが豊富なことからrectを選びました．

実装していく中で気を付けた点はreactの流儀にのっとって実装を進めたことです．無駄のないクリーンなコードをかけるように意識して書きました．
reactの流儀↓

https://ja.legacy.reactjs.org/docs/thinking-in-react.html

流れとしては以下の通りです．
・UIをコンポーネントの階層構造に落としこむ
・Reactで静的なバージョンを作成する
・UI状態を表現する必要かつ十分なstateを決定する
・stateをどこに配置するべきなのかを明確にする
・逆方向のデータフローを追加する

### Next.js
フレームワークではルーティングを楽にしてくれるNext.jsを使いました．ちょうどappルータがstableになった時期だったのでappルータの新機能をいろいろ使ってみたいという思いもありました．
サーバかクライアントのどちらでレンダリングできるのか選択できるのもとても便利だと思いました．すぐに表示させれる部分だけ表示させ，サーバ側の情報が必要な場合はSuspenseを利用して，ローダーを表示することで，ユーザ体験が非常に高くなったと思います．その分設計を考えるときに考えることが増えると思うのでそこは大変そうですね．

# Redux
状態管理はreact-hookと迷いましたが，後々アプリが大きくなったときにライブラリは必要になると思ったのでreduxを利用しました．


# supabase 
バックエンドにBaasを採用した理由としては，学習コストの面が大きかったです．はじめはgoを勉強してがっつり書きたいなと思っていたのですが，そうなるとgoだけでなくサーバ関連の知識(DB, API設計, セキュリティなど)も幅広く学ばなくてはいけなくなりますが，とりあえず動くサービスを作りたいと思っていたので、baasを採用しました．firebaseではなく，supabaseにした理由としてはRDBだったからです．Mysqlを触ってた時期があって，RDBはすこし扱いに慣れていたのでsupabaseにしました．
また無料でずっと使えるという点も大きなポイントでした．

# 機能でこだわった点
・読み込み中のアニメーション
・ランキング
・コメント

>読み込み中のアニメーション

サーバ側からデータを取得して表示させるときは，先に表示できるものだけ表示し,データの取得が必要な部分は`<Suspense>`を利用してローダーを付けたり，投稿や削除などをする時のサーバ通信の間もローダーを表示させるなどして，ユーザ体験がよくなるように工夫しました．

またタイピングアニメーションでテキストを表示させたり，アニメーションをつけたりして，ユーザを退屈させないよう工夫をしました．

<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3162990/5247e993-b405-b537-75c3-c18e7f22db78.png"><img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3162990/cdb748e1-de82-8d44-7100-0a2d80b6b061.png">

アニメーションに関してはこちらを使わせてもらいました．
https://codepen.io/TheDutchCoder/pen/VwMJJB

# 最も苦労したこと
自分がこのをアプリ作る上で，もっとも大変だったことは
<strong>ゲームロジックの実装</strong>と，<strong>Next.js13の情報収集です．</strong>

>ゲームロジックの実装

入力されたキーの正誤判定や，次のテキストへ行く判定を考えるのがとても大変でした．初めて作るWebアプリということで右も左も分からないなか，どれが最適なアルゴリズムなのかなと考え，いろいろな方法を試しては，何回も作り直したりしました．また，AIがテキストを送ってくるのですが，こういう形式で返してといっても，なかなかその通りに送ってくれないことも多々あったりして，AIの扱いも大変でプロンプトをいろいろ工夫して，何度もAIと対話を重ねてきました笑

>Next.js13の情報収集

僕がこのアプリを作るときにちょうどNext.jsの最新バージョンのappルータ―がstableになったので，詳しく解説している記事があまりなく，情報を集めるのがとても大変でした．なので公式ドキュメントや海外のサイトなども積極的に読みました．より幅広い情報を収集し，それらの情報の中から必要な情報を自分なりにまとめ，実装したい機能に落とし込む，というようなプロセスで開発を進めていくようにしました．英語は結構苦手でしたが，公式が出している英語の動画なども積極的に見るなどして，情報の幅を広げました．公式ドキュメントは電車の隙間時間やバイトの休憩中などにも見るなどして，本当に何回も読みこみました．

next.js公式ドキュメント↓

https://nextjs.org/docs

supabase(next.js)公式ドキュメント↓

https://supabase.com/docs/guides/getting-started/quickstarts/nextjs

# 最後に
この記事を読んでいただきありがとうございました．
初めてで分からないことが多い中開発していくのはとても大変でしたが，とてもいい経験になったと思います．今回はバックエンドをBaasにしましたが，今後はgo言語やサーバサイド関連も学び，フルスタックに幅広く開発したいと思っています！



## 今後追加してみたい機能
・ユーザがテーマなどを指定して，プロンプトの設定を自由にできるようになったら好きなジャンルのテキスト(好きなアニメのセリフなど)でタイピングができ，とても面白くなると思いました．
・間違えたキー情報をもとに，AI分析機能を搭載し，どのようなキーを間違えやすいのかなど，分析してくれる機能があれば，よりタイピングが上達するのではないかと思いました．
・生成されたテキスト情報を管理し，みんなの作ったおもしろテキスト，みたいな形で共有し，いいねなどができたら面白いなと思いました．

アプリ（旧バージョン）↓
https://ai-typing.net