尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗友達の人数・今日の気分・使える時間・予算を選ぶだけで、今日みんなで遊べるSteamゲームを5本だけ提案するサイト。 自分で条件を絞って探したい人向けに、チェックボックス式のブラウズ画面も用意している。
/ トップページ/quiz 4問の診断フロー(人数[1人(ソロ)〜6人以上]→気分→時間→予算)→ /result で当日固定のおすすめ5本を表示/browse 自分で人数・気分・時間・予算をチェックボックスで組み合わせて絞り込む一覧(ゲーム名検索・ページネーション付き)/games/[appid] ゲーム個別ページ(SEO・将来の広告枠用)data/games.json に964本のゲームデータ(手動選定36本 + 自動発見928本)/ja/...)・英語(/en/...)のロケール別ルーティング。接続元の国情報(Vercelデプロイ時)またはブラウザ言語から自動判定し、ヘッダーの言語切り替えセレクタで手動変更も可能next-intlを使ったロケール別ルーティング(src/app/[locale]/...)。
src/messages/ja.json / src/messages/en.json に完全翻訳済み。新しい言語を追加する場合は「routing.tsのlocalesに追加」+「対応するmessages/*.jsonを書く」だけでよいx-vercel-ip-countryヘッダー。Vercelにデプロイした場合のみ有効) → ③ブラウザのAccept-Language → ④既定値(日本語)
src/middleware.ts(Next.js 16ではproxy.ts)のCOUNTRY_TO_LOCALE。今は日本→jaのみ登録、それ以外は英語にフォールバックする設定。ここに追記するだけで対応国を増やせるl=japaneseで1回だけ取得しており、UI文言はSteamと無関係に管理している。ゲームのshortDescription(説明文)は取得した言語のまま(Steamが日本語ローカライズしていないタイトルは英語のまま)表示される。これを各言語に翻訳してキャッシュする仕組み(DeepL等)は次のステップとして保留中(下記「データの既知の限界」参照)「みんなで」だけでなく一人プレイしたい人にも対応するため、人数の選択肢に「1人」を追加した。
scripts/add-singleplayer-flag.mjs: 各ゲームがSteamの「シングルプレイヤー」カテゴリ(id=2)を持っているかを追加取得するマイグレーション(既存964件に対して一度実行済み。964件中882件がソロ対応と判定)discover-and-build.mjs / fetch-curated-games.mjsの実行では、この情報を最初から取得するようになっている(マイグレーションは初回だけでよい)coop.singlePlayer === trueのゲームのみ表示する(matchesFilters, src/lib/games.ts)2段階のパイプラインになっている。
verified: true)scripts/curated-seed.mjs : 人手で選んだ「みんなで遊べる有名タイトル」のリスト(appid・気分タグ・目安プレイ時間・実際の対応人数)scripts/fetch-curated-games.mjs : 上記リストを元にSteam公式 appdetails API から画像・価格・説明・カテゴリを取得
npm run data:curated
verified: false)scripts/discover-and-build.mjs : 手動リストだけでは「知ってるゲームばかり」になってしまうため、以下の手順で知名度は高くないが質は担保されているゲームを大規模に自動発見する
npm run data:discover # 候補6000件を評価(既定値)
node scripts/discover-and-build.mjs 3200 12 # 候補上限・カテゴリごとのページ数を指定
store.steampowered.com/search/results(公式検索フロントエンド)を使用appreviews API でチェックし、レビュー300件以上 かつ 高評価率75%以上のものだけ採用(品質ゲート。無名だが質の低いゲームを弾く)appdetails で type=game かつ協力/マルチカテゴリ持ちのものだけ最終採用mood-classifier.mjs(ジャンル+説明文のキーワードマッチ、EN/JP対応)で気分タグを推定data/games.json(手動選定+これまでの自動発見分)は保持したまま、新規に見つかった分だけ追加。差分実行なので同じappidを何度も評価し直さないdata/games.jsonへ途中経過を保存するため、数十分〜1時間規模のバッチが中断しても採用済み分は残る品質の閾値(レビュー300件・高評価率75%)はscripts/discover-and-build.mjs内のQUALITY_MIN_REVIEWS/QUALITY_MIN_POSITIVE_RATIOで調整可能。閾値を上げるほど有名タイトル寄りに、下げるほど無名タイトルも混ざりやすくなる。
scripts/fetch-steam-data.mjs : 上記2つを作る前の試作版(参考用、実運用では使っていない)SteamSpyは使っていない: Cloudflareのボット判定(403)でブロックされており、突破する行為は避けたため、Steam公式のストアフロントAPI(search/results / appreviews / appdetails)のみで完結する設計にしている。
レート制限について: Steamの検索APIは短時間に集中アクセスすると429(Too Many Requests)を返すことがある。discover-and-build.mjsは429を検知すると5秒→10秒→…と待機して自動リトライする。1000本規模のバッチは数十分〜1時間程度かかる想定。
estimatedSessionMinutes(プレイ時間の目安)とminPlayers/maxPlayers(対応人数)はSteam APIに存在しない項目のため暫定値(2〜4人)。将来的にはHowLongToBeat等の外部データに置き換えたいmoodTags(気分)はmood-classifier.mjsによるジャンル+説明文のキーワードマッチ(自動発見タイア)または人手判断(手動選定タイア)。1000本規模になるとキーワード分類の精度には限界があるため、質の担保はあくまでレビュー数/高評価率のフィルタが主。より精度を上げるならshortDescriptionをLLM(Claude Haiku等)に分類させる案が安価(1本あたり数銭程度)で精度も出やすいが、API課金が発生するため導入は要判断shortDescription)はSteamが日本語ローカライズしていないタイトルの場合、英語のまま表示される(UIのロケールを英語に切り替えても、この文章自体はSteamから取得した言語のまま変わらない)。DeepL等での翻訳キャッシュ導入は保留中で、導入すればこの制限は解消できるcc=パラメータを変えてSteamから再取得する必要があり、翻訳と同様「言語ごとに再取得」のコストがかかるため、現時点ではスコープ外としている)現状は手元でnpm run data:updateを手動実行する想定。差分実行に対応しているので、定期的に回せば新しく人気が出たゲームや新作が自動で追加されていく。完全に無人で回すには:
schedule(cron)でnpm run data:updateを週1回実行data/games.jsonに差分があれば自動コミット → Vercel/Cloudflare Pagesが自動で再デプロイ実装にはGitHubリポジトリ化が前提。
構成案(低コスト優先):
| 項目 | 推奨 | 理由 |
|---|---|---|
| フレームワーク | Next.js (App Router) | SSG/SSRでSEOに強く、generateMetadata・sitemap.ts・robots.tsが標準搭載 |
| ホスティング | Vercel無料枠 or Cloudflare Pages | 個人トラフィック規模なら無料枠で十分。静的+一部動的(/result,/browse)构成でも問題なく動く |
| データ更新 | GitHub Actions cron → 再デプロイ | サーバー常時稼働が不要。実行時のみ課金/無料枠消化 |
| 画像 | Steam CDN直リンク(next/imageのunoptimized) | 自前で画像を持たないので配信コストがかからない |
| 広告 | 現時点では未実装 | Google AdSenseはサイト審査・アカウント発行が必要で、ユーザー本人の作業が必要なため。ある程度コンテンツ(ゲーム数・PV)が育ってから申請するのが通りやすい |
SEO観点で今回やったこと:
generateMetadata(タイトル・description・OGP)/result?players=...&mood=... のようなクエリ付きURLで「3人・怖い・1時間・無料のおすすめ」的なロングテール検索に対応できる形にした/games/[appid])をgenerateStaticParamsで静的生成し、個別ゲーム名での検索流入も狙える形にしたsitemap.ts / robots.ts で自動生成まだやっていない(次のステップ):
npm install
npm run dev # http://localhost:3000
npm run build