Skip to content

audit/2026-09-08: ツール検索・お気に入り・最近使ったツール・モバイルヘッダー・calculate イベント拡張 - #4

Merged
appdevelopsk merged 1 commit into
mainfrom
audit/2026-09-08-search-favorites
Sep 8, 2026
Merged

appdevelopsk merged 1 commit into
mainfrom
audit/2026-09-08-search-favorites

Conversation

@appdevelopsk

Copy link
Copy Markdown
Owner

概要

ログイン不要・localStorage のみで完結する UX 改善をまとめて追加します(サーバ状態なし)。223 個のツールファイルは一切変更していません。

変更内容

  1. ツール検索
    • /tools ページ検索と、ヘッダー検索(デスクトップ: インライン入力+ドロップダウン/モバイル: アイコン→検索バー展開)を共通マッチャー lib/search/matcher.ts で実装。
    • 一致対象: ローカライズ済みタイトル・slug・カテゴリキーワード(各言語 + 英語フォールバック)・説明文。大文字小文字無視、前方一致 > 部分一致でスコアリング、上位 10 件をリンク表示。
    • / で検索にフォーカス(ページ検索がヘッダー検索より優先)、Enter で先頭の結果を開く、Esc で閉じる。
    • GA4 tool_search {query_length, results_count} をデバウンス送信。
    • クライアントバンドルにはツール名の翻訳が含まれないため、静的ルート /{locale}/search-index.json(force-static、全ロケール生成)を追加し、初回フォーカス時に遅延取得します。
  2. お気に入り
    • ツールページ見出しに星トグル。toolify_favorites_v1(slug 配列)。旧キー toolify:favorites からの移行あり。
    • ホームと /tools の先頭に「お気に入り」セクション(空なら非表示)。GA4 favorite_toggle {tool_slug, state}。
  3. 最近使ったツール
    • ツールページ表示時に toolify_recent_v1 へ MRU で push(最大 8、重複排除)。ホーム・/tools に「最近使ったツール」行。
    • useSyncExternalStore + 空のサーバスナップショットでハイドレーション差分なし。
  4. モバイルヘッダー(<sm)
    • Logo + 検索アイコン + メニューボタンのみに。All tools / AI prompts / About / 言語切替はメニュー内へ。デスクトップは変更なし。
  5. calculate イベント拡張
    • ToolInteractionTracker のみで tool_category / locale / input_count / has_result を付与。
  6. i18n: nav.menu, nav.closeMenu, tool.recent, tool.search*, tool.categoryKeywords.* を 17 ロケールすべてに追加。

検証

  • npx tsc --noEmit: OK
  • npm run audit:i18n: ✓ i18n consistency OK
  • npx vitest run src/lib/search: 6 passed(新規 matcher.test.ts)
  • next lint: リポジトリに ESLint 設定がなく対話プロンプトになるため未実行
  • フルビルド(223 ツール × 17 ロケール)は時間の都合で未実行。プレビュー環境での確認をお願いします。

未実施・注意点

  • 検索は完全なクライアント側実装で、サーバ検索やインデックス事前生成はありません(1 ロケールあたり JSON 数十 KB)。
  • ヘッダー検索の実機(iOS Safari)での表示確認は未実施です。

https://claude.ai/code/session_01AcLxcZtf35XLpenzFXTpUC

…eader, richer calculate event

Why:
- 223 tools with no way to find one except scrolling category lists. Adds a
  shared matcher (title/slug prefix > substring > keyword > category words >
  description, top 10) used by the /tools page search and a new header search
  (desktop: inline input + dropdown; mobile: icon that expands a bar).
  `/` focuses search (page search wins over header via a priority registry),
  Enter opens the first hit, Esc closes. GA4 `tool_search` is debounced.
- The client only receives common messages, so localized titles for the header
  search come from a new static per-locale route `/{locale}/search-index.json`
  (fetched lazily on first focus; middleware skips dotted paths).
- Favorites (`toolify_favorites_v1`, migrates legacy `toolify:favorites`) and
  recently used (`toolify_recent_v1`, max 8) live in localStorage only and are
  read via useSyncExternalStore with an empty server snapshot, so SSR/hydration
  never differ. Both show as shelves on home and /tools when non-empty.
- Mobile header (<sm) is now Logo + search icon + hamburger; nav links and the
  language switcher move into the sheet. Desktop layout unchanged.
- `calculate` now carries tool_category, locale, input_count (filled inputs)
  and has_result (any non-empty aria-live/output/result element) computed in
  ToolInteractionTracker only; no per-tool files touched.
- New i18n keys (nav.menu/closeMenu, tool.recent/search*/categoryKeywords)
  added to all 17 locales; audit:i18n passes.

Claude-Session: https://claude.ai/code/session_01AcLxcZtf35XLpenzFXTpUC
@appdevelopsk
appdevelopsk merged commit db807f4 into main Sep 8, 2026
2 checks passed
@appdevelopsk
appdevelopsk deleted the audit/2026-09-08-search-favorites branch September 8, 2026 06:09
appdevelopsk added a commit that referenced this pull request Sep 18, 2026
index 対象ページの関連リンクが noindex ページへ向いていた問題 (#3) と、
どこからも関連リンクを貰えない index 対象ページ (#4) をまとめて是正する。

#3 権威漏れ:
  getRelated に indexableOnly を追加し、index 対象ページでは index 対象だけを
  関連に出す。実測で 378 本中 112 本 (29.6%) が noindex 先に向いていた。
  既定は false のままとし、noindex ツールのページは従来どおり全ツールから
  関連を出す (利用者向けの導線であり、クロール上の損が無いため)。

#4 孤児:
  fill をレジストリ登録順で埋めていたため、カテゴリ内の先頭付近ばかりが
  関連に出て末尾のツールが孤児になっていた (#3 適用後も15件)。
  明示 related の被リンク数 (index 対象ページからの分のみ) が少ない順に
  埋めるよう変更する。同数なら slug 順で固定しビルド間で揺れないようにした。
  ※被リンク数の集計で getRelated を呼ぶと相互再帰になるため明示 related のみ数える。

実測 (ビルド出力の HTML で検証):
  関連リンク総数      378 → 374
  noindex 先          112 → 0
  関連が3件未満のページ  7 → 0
  被related 0 のページ  21 → 0  (被リンク分布 min=1 / median=6 / max=14)
  noindex ページ160件は平均5.98件で従来どおり (関連0件は無し)

一覧の表示件数は 223 件のまま変更していない (ken 判断)。

Claude-Session: https://claude.ai/code/session_01ENHPNZ5ngcdrTHJ2H6oAFd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant