リンクがデータを失う理由:パラメーターとフラグメントを修正する
URL の & と # を区別し、二重エンコードを避けます。WikiURL とブラウザーで、実際に共有するリンクと検索結果を確認します。

開いたページが期待したデータを受け取るとは限らない
コーヒーとお茶を検索するリンクを作りました。ページは開きますが、結果が意図と合いません。サーバーや短縮サービスを疑う前に、共有した正確なアドレスを確認しましょう。架空の例の q=cafe&te は、一般的なフォームパラメーターの解釈では単一の cafe&te という値になりません。& が項目を区切るからです。また、#precios はフラグメントを示します。実際に試す前に example.invalid を、その検索を受け付ける自分のページに置き換えてください。
診断を三つの問いに分けます。どのページを開きたいか、何のデータを受け取るべきか、その後どの部分を見せたいかです。ボタンの表示文字だけではなく、リンクの URL をコピーします。編集前に参照用の版を保存してください。このガイドは構成要素を見直し、WikiURL で結果を確認する方法を示します。すべてのサイトが q を認識することや、成功応答が正しい検索結果を意味することは約束しません。
https://example.invalid/buscar?q=cafe&te#preciosアンパサンドが文字列の一部なら区切りに使わない
文字通り cafe & te を検索する場合、& は q の値に含まれます。URLSearchParams でパラメーターを作るときは、エンコードしていない文字列を渡します。シリアライズ時に、その文字は %26 になります。MDN は、このインターフェースがパラメーターを文字列にするときにフォームのエンコードを適用し、空白を + で表すと説明しています。URL の & をすべて置き換えるという意味ではありません。意図的なパラメーター区切りもあるためです。
JavaScript の例はベースからアドレスを作り、検索値を設定し、フラグメントを別に加えます。ローカルの JavaScript 環境で実行すれば、架空のドメインへ検索を送らず結果を見られます。プログラムを書かない場合は、文字列を手作業でつなげる代わりに、自分の検索ページが生成するリンクを使ってください。期待する値とサイトの結果を比べます。%26 が見えるだけでは、特定のアプリがデータをどう解釈するかは分かりません。
const url = new URL("https://example.invalid/buscar");
url.searchParams.set("q", "cafe & te");
url.hash = "precios";
console.log(url.href);
// https://example.invalid/buscar?q=cafe+%26+te#preciosフラグメントはサーバーが受け取るパラメーターではない
MDN によると、# の後のフラグメントはクライアントで処理され、リソースのリクエスト時にサーバーへ送られません。ページはこれを precios のようなセクションへの移動や、別のアプリ動作に使えます。したがって q=cafe#te では、そのリクエストでサーバーが受け取る値に te は加わりません。# を検索文字列に含めるなら、値の中では %23 と表します。三つ目のアドレスがその例です。
二つの効果を別々に確認します。検索が期待した結果を示すことと、フラグメントが目的の場所へ進むことです。セクションが存在するか、アプリがそのフラグメントを認識する必要があります。サーバーからサイトを取得する確認ツールだけでは、ブラウザーがセクションへスクロールすることを確かめられません。すべてのフラグメントを削除する万能修正も避けます。受け取る人が必要としていた部分を消す可能性があります。
https://example.invalid/buscar?q=cafe%23te#precios値を一度だけエンコードし、アドレス全体は対象にしない
RFC 3986 は構成要素を区切る文字とデータを区別し、同じ文字列の繰り返しエンコードやデコードに注意を促します。未エンコードの値を期待する関数へ cafe%26te というエンコード済み文字列を渡すと、パーセント記号が %25 になり、%2526 が現れる場合があります。層を追加したのであって、目的の検索を自動的に保ったわけではありません。例の二行で変化を見分けられます。
修正はデータの出所によります。人が入力した文字列なら、パラメーターを作るインターフェースへ未エンコードで渡します。既に有効な完全 URL なら、アドレス全体を一つの値として再エンコードしないでください。各関数やフォームが何を受け取るか記録します。%、&、# の一括置換は避けます。正しい区切り、必要なパラメーター、変更するつもりのないパスを変えるおそれがあります。
q=cafe%26te
q=cafe%2526te応答は WikiURL、内容はブラウザーで確認する
実際の公開アドレスができたら、WikiURL の URL 確認ツールに貼り付けます。返された HTTP ステータスと最終的な移動先を見ます。実装はサーバーから問い合わせ、リダイレクトを追うため、意図しない移動先を見つける助けになります。管理リンク、パスワード、非公開データを含むアドレスを貼り付けないでください。例の example.invalid は架空の移動先なので確認しません。
実際の版をブラウザーでも開き、検索とセクションを見ます。成功応答でも、期待したフィルターを適用せずにページが表示される場合があります。リダイレクトがあれば、参照版とパラメーターを比べ、ブラウザーでフラグメントを観察します。確認ツールはアプリのロジックを解釈せず、安全性の認証やアカウントの閲覧権限の証明もしません。応答の証拠と機能確認を合わせることが目的です。
ほかの人が受け取るコピーを試す
最終リンクを共有予定の場所に貼り付け、広く配布する前にそのコピーを開きます。文末の句点を含めていないか、コピーで部分が欠けていないか、表示文字を移動先と取り違えていないか確認します。公開すべき内容は管理者セッションに依存せず試してください。QR にする場合は、元のファイルに加え、スキャンで表示されるアドレスも確認します。
簡単な記録を残します。元のアドレス、期待する検索値、予定したフラグメント、共有 URL、観察結果です。失敗したら該当する構成要素に戻り、修正後に再度試します。確認済みの版だけを公開してください。こうすれば、パラメーター構築の問題、移動先を変えるリダイレクト、ブラウザーの動作を区別でき、開くリンクを「送ろうとした全データが保持される保証」と扱わずに済みます。