DocusaurusにGitHubスターの応援ボタンを実装した備忘録
コンテンツへの共感を可視化し、サイト運営のモチベーションを高めるため、各記事に「GitHubスターの応援ボタン」を設置しました。
既存のバッジサービスや公式ボタンを使用せず、サイトのデザインに完全に調和する独自コンポーネントを作成しました。この記事では、OAuth認証を回避した設計判断や、GitHub APIのレート制限対策、Docusaurus特有の実装テクニックについて記録します。
完成したコンポーネントは上記の通り動作します(よろしければ応援のスターをお願いします🌟)。
設計方針:シンプルさとユーザー負担の軽減
GitHubのスター機能を実装するには、通常OAuth認証やバックエンドが必要になりますが、今回はあえて「リポジトリページへの遷移方式」を採用しました。
OAuth認証は、単にスターを押したいだけのユーザーにとって心理的・操作的なハードルとなります。 「クリックでリポジトリを開き、そこでスターを押してもらう」 というシンプルなフローを採用することで、開発コスト(バックエンド不要)とユーザー負担の両方を最小化しました。
実装ファイルの詳細
実装は、以下のコンポーネントとスタイル定義で行いました。
src/components/GitHubStarLink/index.tsx(View on GitHub)src/components/GitHubStarLink/styles.module.css(View on GitHub)
以下、技術的なハイライトです。
1. APIレート制限対策とキャッシュ (index.tsx)
GitHub API(認証なし)には、1時間あたり60リクエストという厳格なIP制限があります。記事を閲覧するたびにAPIを叩いていると、すぐに制限に達してしまいます。
そこで、sessionStorage を活用した簡易的なキャッシュ機構を実装しました。
// キャッシュの有効期限 (30分)
const CACHE_DURATION = 1000 * 60 * 30;
// ...
useEffect(() => {
const fetchStars = async () => {
const cacheKey = `gh-stars-${repo}`;
// 1. キャッシュの確認
try {
const cached = sessionStorage.getItem(cacheKey);
if (cached) {
const { count, timestamp } = JSON.parse(cached);
// 有効期限内ならキャッシュを使用し、APIコールをスキップ
if (Date.now() - timestamp < CACHE_DURATION) {
setStarCount(count);
return;
}
}
} catch (e) { /* ignore */ }
// 2. APIコール
try {
const response = await fetch(`https://api.github.com/repos/${repo}`);
if (!response.ok) throw new Error('API Error');
const data = await response.json();
setStarCount(data.stargazers_count);
// 3. キャッシュの更新
sessionStorage.setItem(cacheKey, JSON.stringify({
count: data.stargazers_count,
timestamp: Date.now()
}));
} catch (error) {
// エラー時はフォールバック(カウント非表示など)
}
};
fetchStars();
}, [repo, showCount]);
2. スタイリングとi18n対応 (styles.module.css)
デザインはGitHubのUI文脈を踏襲しつつ、Docusaurusのテーマ(ライト/ダークモード)に自動追従するように調整しました。
特にライトモード時、白いバッジが背景に埋没しないよう、薄いグレーの背景色と境界線 (border) を適切に設定しています。
/* ライトモード:色味を抑えたクリーンなデザイン */
.container {
background-color: rgba(0, 0, 0, 0.02);
border: 1px solid rgba(0, 0, 0, 0.08);
/* ... */
}
/* ダークモード:透過レイヤーで背景から浮き上がらせる */
[data-theme='dark'] .container {
background-color: rgba(255, 255, 255, 0.03);
border-color: rgba(255, 255, 255, 0.1);
}
また、@docusaurus/Translate を使用して、多言語(英語/日本語)切り替え時にメッセージが自動で翻訳されるように実装しています。
コンポーネントの使用方法
MDXファイル内でコンポーネントをインポートして配置します。
import 文は必ずファイルの最上部(Front Matterの直下)に記述する必要があります。<!-- truncate --> マーカーより下に記述すると、ブログ一覧ページの生成時にコンポーネント解決エラーが発生する可能性があります。
---
title: 記事タイトル
---
import GitHubStarLink from '@site/src/components/GitHubStarLink';
記事の本文...
<GitHubStarLink repo="hiroaki-com/hkdocs" />
まとめ
OAuth認証や複雑なバックエンドを排除し、フロントエンドの工夫(キャッシュ制御)のみで実用的なスターボタンを実装できました。ユーザー体験を損なわず、かつサイトのデザインに完全に馴染む機能を実装できたことは、外部サービスに依存しない自作ならではのメリットです。
なお、現在は記事ごとに import 文を記述していますが、Docusaurusの MDXComponents 機能を使用すればグローバルにコンポーネントを登録できるため、将来的にはインポート不要でタグのみ記述できるよう改善する予定です(To-Be案件)。