メインコンテンツまでスキップ

ブログにいいね・コメント機能を追加した——GiscusとAWSで迷った話

· 約5分
Rintaro Nakahodo
NLP Researcher · Engineer · Creator

ブログに「いいね」と「コメント」を実装した。note.com のようにハートボタンがついていて、記事の下にコメントが書ける、あの機能だ。

実装自体は数時間で終わったが、「どうやって作るか」を決めるまでの検討が面白かったので記録しておく。

きっかけ

note.com の記事にあるハートボタンを見て、自分のブログにも欲しくなった。読んだ人が何か感じたとき、それを残せる場所がある方がいい。コメント欄があると、記事が一方通行でなくなる。


まず頭に浮かんだのはAWS

エンジニアとして最初に思いつくのは自前実装だった。構成案はこうなる:

  • いいね数の保存: DynamoDB(記事パスをキーにカウントを保持)
  • API: Lambda + API Gateway(GET/POSTのシンプルなエンドポイント)
  • コメント: RDS or DynamoDB + Lambda

メリットは明確で、完全な自由度がある。匿名でいいねできるし、UIも自分で作れる。GitHubアカウントが不要なので、技術者以外の読者も参加できる。

ただ、現実的なコストを整理すると微妙になってくる。

項目内容
費用Lambda・API GW・DynamoDBで月数百円〜
実装工数バックエンド構築で数日
維持管理デプロイ・監視・スパム対策が必要
スパム対策自前でreCAPTCHA等を用意する必要

個人ブログのコメント機能のために、インフラを建てて維持し続けるのは費用対効果が悪い。「作りたい気持ち」はあるが、「運用したい気持ち」が追いつかない。


Giscusという選択肢

調べていて見つけたのが Giscus だ。GitHubのDiscussions機能をバックエンドに使うコメントシステムで、いくつかの点でちょうど良かった。

  • 無料・広告なし: GitHubのインフラに乗っかるだけ
  • リアクション対応: ハート・👍・🎉など、GitHubのリアクションがそのまま使える
  • スパム耐性: GitHubアカウントが必要なため、botによるスパムが入りにくい
  • メンテナンスフリー: サーバーを持たないので壊れない

デメリットは一点だけ——コメント・リアクションにGitHubアカウントが必要なこと。

ブログの読者層が技術系・エンジニア中心であれば、GitHubアカウントを持っていない人は少ないと判断できる。読者層が広がって困るようになったら、そのとき自前実装に移行すればいい。

まず Giscus で始めて、物足りなくなったら AWS に移行する、という順番にした。


実装:Docusaurusへの組み込み

ブログは Docusaurus で動いている。静的サイトジェネレーターなので、コメント欄は外部サービスを埋め込む形になる。

1. GitHubの準備

リポジトリの Settings → Discussions を有効化し、Giscus の GitHub App をインストールする。

2. giscus.app で設定を取得

giscus.app で以下を設定:

  • リポジトリ: 自分のリポジトリ
  • Discussion カテゴリ: Announcements(管理者と Giscus のみが新しい Discussion を作れるカテゴリ)
  • ページとの連携: pathname(各記事のURLパスをキーにする)
  • リアクションを有効にする: ✓

設定すると repo-idcategory-id が発行される。

3. @giscus/react のインストール

npm install @giscus/react

4. GiscusComponent の作成

Docusaurus のライトモード・ダークモード切り替えに追従させるため、useColorMode フックを使う。

import Giscus from '@giscus/react';
import { useColorMode } from '@docusaurus/theme-common';

export default function GiscusComponent() {
const { colorMode } = useColorMode();

return (
<div style={{ marginTop: '3rem' }}>
<Giscus
repo="your-username/your-repo"
repoId="R_xxxxxxxxxxxx"
category="Announcements"
categoryId="DIC_xxxxxxxxxxxx"
mapping="pathname"
reactionsEnabled="1"
theme={colorMode === 'dark' ? 'dark_dimmed' : 'light'}
lang="ja"
loading="lazy"
/>
</div>
);
}

5. BlogPostItem/Content をスウィズルして注入

Docusaurus には スウィズルという、フレームワークの内部コンポーネントを差し替える仕組みがある。BlogPostItem/Content を wrap モードでスウィズルし、記事本文の直後に Giscus を差し込む。

// src/theme/BlogPostItem/Content/index.tsx
import Content from '@theme-original/BlogPostItem/Content';
import { useBlogPost } from '@docusaurus/plugin-content-blog/client';
import GiscusComponent from '@site/src/components/GiscusComponent';

export default function ContentWrapper(props) {
const { isBlogPostPage } = useBlogPost();

return (
<>
<Content {...props} />
{isBlogPostPage && <GiscusComponent />}
</>
);
}

isBlogPostPage のフラグで、記事一覧ページには表示せず、記事詳細ページにだけ Giscus を出す。


結果

記事の末尾にハートリアクションとコメント欄が現れた。GitHubのDiscussionsと連動しているため、コメントが投稿されるとリポジトリのDiscussionsに自動で記録される。

AWSで自前実装した場合と比べて、実装時間は数日→数時間、インフラ費用はゼロになった。個人ブログのフェーズとしては、これで十分だと思っている。

物足りなくなる日が来たら、その時はちゃんと AWS を建てよう。

Live with a Smile!