
【アプリ開発日記11週目】Next.jsで自由度の高いテキストエディタを実装する
Wordやnoteのようなリッチテキストエディタを実装したい。
さらに、専用のブロックをカスタマイズ出来るようにしたい。
それを実現できるライブラリが、ありました。
1,なぜカスタムブロックが必要?
今回は開発寄りの話になるため、詳細な内容は技術記事に譲りどんなことが出来るようになるかについてまとめていきます。
最終的に出来上がったUIがこちら。

論文を執筆するうえで欠かせないのがAbstract。ただし、このAbstractのみを使用したい場面が多々あります。例えば「一覧表示で完結に内容を伝えたい時」「さらに短い要約を作る時(AIで論文全体ではなくAbstractのみを読み込ませる)」など。
今回は作りませんでしたが、例えばnoteの「目次」もカスタムブロックですね。
冒頭に表示するだけなら専用のカラムを作れば良いのですが、今回のAbstractや改善後のnote目次(以前は 表示 / 非表示 しか設定できませんでしたが、現在は好きな場所に配置できる、これが便利)では、本文内のカラムに入れつつ、そのカスタムブロックとして認識されなければいけません。
それが実現可能、且つNext.jsと相性が良くて使いやすい、デザインも自由に変更可能……というものを探していて見つけたのが「Tiptap」でした。
2,Tiptap
これがとても使いやすい。幸いAIでも十分学習されているらしく、コードもエラーを出さずに出力してくれます。
他にもProseMirror、Slate.jsなど優れたテキストエディタが数多く存在しますが、普段お世話になっている「しずかなインターネット」で使われている(UIがフォントから使い勝手まで非常に洗練されていて、お気に入りのウェブアプリの1つです)ことが決め手になりました。
そこ?と感じる方もいらっしゃるかもしれませんが、それも含めて好みだと思います、おそらく。
そして実際に出来上がった実際の編集画面が以下。


この中でさらにリスト、太字など編集し保存も可能
最初こそ手間取ることもあるかもしれないですが、基本的には公式のチュートリアル通り進めていけば簡単なエディタが出来上がります。あとは好みのコマンドをAIに聞きながら追加していく、すると上記のようなエディタが出来上がっていきます。
私の場合、データはjsonbで保存。
表示まで無事できました。

おわりに
以前、テキストエディタをライブラリなしで作ろうとした記憶があります。文字を選択し、例えば太字にするボタンを押すと特定の記号で囲まれる、というシンプルな仕組み。
ただ、マークダウン形式に似ているところもありますが、この方法だと思ったとおりに表示されないときが多々あるんです。「これはテキストです」の全体を太字にしようと選択すると「これはテキストです」のようにひっくり返ってしまうなど。
これが表や画像となるとさらに複雑になり、結局マーカーにとどめていた(それでもバグが残った)ので、今回のテキストエディタを使ったときは「本当にnoteやwordみたいにスタイルを変更できる!」と感動しました。
細かなUIは自分で作ったほうが融通が効く場合も多くメインで使っていますが、カレンダーやテキストエディタなど、複雑寄りなものはライブラリの恩恵が大きいですね。
迷っている方は、ぜひ一度試してみて下さい。
今回も最後までご覧いただき、ありがとうございました!