スクールのポータルサイトにブログ機能を追加した振り返り

スクールのポータルサイトにブログ機能を追加した振り返り

投稿日: 2024年09月30日

Tips
要約
  • スクール内で匿名の満足度・要望アンケートを実施し、高い満足度を得た結果、ブログ機能を開設することになった。
  • ブログの運用には、Next.jsを用いたサーバーコンポーネントや動的OGP生成などの技術を活用し、生徒が記事を書ける環境を整えた。
  • 今後は記事の一覧や検索機能、コメント機能などの追加を検討しており、生徒同士の交流を促進したいと考えている。

こんにちは。

先日、スクール内にて匿名式の満足度・要望アンケートを実施させていただきました。

ご協力いただいた皆様、ありがとうございました。
みなさんかなり満足度は高い回答をいただいて嬉しかったのですが、
僕が気づけていなかった点のご指摘もあり、今後1つずつ改善していきたいと思っています。

設問の1つに「スクール内ブログを書いてみたいか」を聞かせていただき、
いただいた回答内では「書きたい」が100%だったので、早速作ってみることにしました。

やりたいことは、こんな感じ。

  • メインの運用目的は、学んだことの言語化+アウトプットによる知識の定着
  • 生徒さん誰でも記事を書ける
  • 記事の内容は、技術的な内容(各章の攻略のコツなど)、オリジナルアプリ開発振り返り、転職活動の振り返りなど。内容はスクールに関係なくてもOK
  • ShiftB会員以外も記事を読める形で公開(転職活動などでも見せれる形に)
  • 個人ブログやQiitaやZennへの記事流用、その逆も可

開発期間2日でしたが、
頑張った点や学びのあった点など、まとめていきます。

デザイン

Figmaでざっくりとだけ、作りました。

ブログ機能、いざ運用開始してみたものの、あまり使う人がいないという未来も考えられたので、
まずはできるだけミニマム機能で出そうと思いました。

スマホデザインは作らずに実装しましたw

開発

基本的な技術構成は、Next.js + Supabase + Prismaで、
皆さんが学習している内容と同じです。

今回の開発で悩んだポイントや、初めてやって勉強になった点を4つ紹介します。

1. 記事をどこで書くか

記事を書く画面をどうしようか一番の悩みで、エディタを0から作っても楽しそうですが、
「ミニマム機能でリリース」を考えた時に、
エディタを作るのはかなり時間がかかりますし、
かといって突貫実装でエディタがお粗末だと、使いづらいから書かない、となってしまえば本末転倒。
今回はmicroCMSの管理画面で記事を書いて、それをポータルサイト上で閲覧する方式にしました。

ただし、誰が書いたのかなど、ポータルサイト上のユーザー情報と紐付けたかったので、
microCMSのアカウントは皆さん共通にしつつ、
記事を書く画面に「ポータルサイトのユーザーID」の入力欄を設け、
これを各自、執筆時に入力いただくことで、ユーザー情報と紐づけることにしました。

もしブログ文化が定着して長く続きそうであれば、
将来的にはエディタを開発し、ポータルサイト内で記事を書けるようにして、
microCMSの記事データも移行しようと思います。

2. サーバーコンポーネント

Next.jsのv.13から登場した新機能で、文字通りサーバー側でコンポーネントの処理を実行するというもの。

この記事でサーバーコンポーネントの詳しい説明はしないですが、
ブログサイトであればSEO面も意識したいので、
クローラーが直接HTMLを解析できるサーバーコンポーネント(SSR)は必須だなということで、使いました。

一昔前はSSRという書き方がメインでしたが、サーバーコンポーネントの概念がでて、だいぶ開発しやすくなっていました。(やってることはほぼ同じ)

ざっくり、Reactコンポーネント内で以下のような書き方ができます。

const Page = async ({ params: { id } }: Props) => {
  const profile = await prisma.profile.findUnique({
    where: {
      id,
    },
  });

  return (
    <div className="">{profile?.name}</div>
  );
};

サーバー側で実行されるので、マウントなどの概念がなく、故にコンポーネントの関数を非同期(async)にできます。

また、apiリクエストなど行わず、直接コンポーネントからprismaを使ってデータを取得できます。

この処理がクライアント側で行われてしまうと、DBのURLなどが露出してしまうのでセキュリティ的にNGなのですが、
このコンポーネントがサーバーサイドで実行されるので、セキュリティ上も問題なく、かつ処理も早く、さらにはクライアント側の処理の量も減らせるというメリットがあります。

とても良い機能なのですが、React初学者にはあまりお勧めできないかもしれません。
現状、Next.jsでバックエンド含めて作っている会社さんってまだまだ少ないです。
バックエンドはRubyやPHP、とプロジェクトごと分けているところが多く、
その場合、Next.jsを使うメリットはあまりなく、クライアントコンポーネントのみでの開発が主流です。
なので、初学のうちはあまり手を出さない方がスキルの汎用性的にはおすすめです。
(ShiftBのカリキュラムでもサーバーコンポーネントは扱わず、全てuse clientしてもらっているのもこの理由です。)

3. 無限いいねボタン

自分は人のブログを読んでいて、よく、いいねが1回では足りないと感じることがあります。

特に、悩んでいる中でドンピシャの記事を見つけたときは、100回くらいいいねしたくなります。

ということで、そのようないいね機能実装してみました。

複数回押せるようにすることで、自ずと押したユーザー情報との紐付けが不要になります。

なので、ログインしていないユーザーでもいいねを押せるのがメリットかなと思います。

逆にデメリットとは、自分がいいねしたのかどうか分からなくなってしまう点がありますが、SNSでもないですしあまり重要ではないかなと思い、決めました。

実装的には、連打のたびにDB保存処理を行っていたら大変なので、「1度クリックされてから、1秒以上次のクリックを検知しなかったら、その間クリックされた回数をまとめて保存」という処理にしました。

スマホ表示の場合、押しやすい位置にあるので、たくさん押してみてください。

ちなみに、いいねボタンに表示する絵文字の種類は、microCMSの記事作成画面から指定できます。

4. OGP画像生成

一番苦労したのがこちらの機能です。(徹夜しましたw)

QiitaやZennの記事URLって、LINEやSNSで共有された時に、文字が入った画像が表示されますよね。

あの画像はOGP画像で、Webサイトが各SNSなどのクローラーに引き渡すことで表示されていますが、

画像内に記事タイトルが入っているということは、記事によって動的に画像を生成する、ということをやっています。

確かに、記事のリンクをもらった時に画像に情報が書いてあると読みやすいと感じるので、作ってみることにしました。

一昔前(10年前とか、例えばクックパッドのレシピ詳細ページのOGP)などは、記事公開時にダミーのページを作成して、そこにOGPの見た目をHTMLで作成し、その画面をスクリーンショットする形で実装をしていたようです。

それがここ数年は、imgixなどの画像生成用のサービスを使って割とお手頃に作れるようになっていて、

自分もそれらを使うのかなと思っていましたが、

なんとNext.js、その辺りの機能もフレームワーク内に組み込まれていました。

例えば、src/app/blog/[id]/page.tsxのOGPを動的に作りたければ、

src/app/blog/[id]/opengraph-image.tsxというコンポーネントファイルを作って、そこに 1200*630サイズのUIをReactで実装してあげれば、

それが画像に変換されて、OGP画像になるというものです。

しかも、このコンポーネントでもpropsでidを受け取れるので、opengraph-image.tsx内でAPIなどを使ってデータ取得すれば、記事のタイトルや執筆者の情報もコンポーネントに埋め込んだ状態で画像化できるというものです。

ただ、opengraph-image.tsxは一癖あって、実行される場所がエッジサーバー上という特徴があります。

そのため、prismaクライアントが使えなかったり、Font情報を普通の方法では取得できなかったりなど、細かいトラップがたくさんあったのですが、

なんとか実装できました。

(この動的OGP生成機能、もしオリジナルアプリで作りたい方いたら、ポータルサイトのリポジトリお見せします。)

まとめ・今後追加したい機能

最低限の機能で実装までしましたが、今後、追加したい機能が盛りだくさんです。

  • 記事の一覧ページ
  • 記事の検索機能
  • カテゴリー毎の一覧ページ
  • ユーザー毎の記事一覧ページ(記事を書き溜めて、転職活動の際などに活用いただきたい)
  • 記事へのコメント機能(スレッド形式)
  • 記事の末に関連記事の表示
  • Instagramへのシェア機能(公式のシェア機能はないので、ストーリーズサイズの動的画像の生成)
  • 教材のチャプター詳細ページに、関連記事の表示(学習時に欲しい情報に出会えるように)

この辺り、実務課題として、皆さんにも体験していただきながら作って行けたら良いなと思っています。

また、生徒さんの書いた記事は、ぶべコードアカウントでもどんどんシェアさせていただき、
生徒さんと僕のフォロワーさんがつながるみたいな現象が起きれば、面白いかなとも思っています。

シェア!

Threads
icon
ぶべ
Webの修行中 / 個人開発奮闘中 / ベンチプレス110kg / Reactの先生
Loading...
記事一覧に戻る
Threads
0