有料会員制WordPressサイト向け検索モーダルの構築

ほとんどのWordPress検索チュートリアルは単純すぎます。ヘッダーにウィジェットを配置するだけといった内容です。これは公開ブログには機能しますが、メンバーシップサイトでは通用しません。

有料コースやプライベート動画がある場合、デフォルトの検索機能はデータを漏洩させる可能性があります。ログアウト中のユーザーに対して非公開コンテンツのタイトルが表示されてしまい、ペイウォール(支払い障壁)が台無しになります。

私はWordPress、WooCommerce、LearnDashを使用して、フィットネスサイト向けのカスタム検索モーダルを構築しました。ここでは、アクセス権限を尊重した検索機能の構築方法を紹介します。

アーキテクチャ

コンテンツタイプごとに個別の検索を行うのではなく、単一の統合インデックスを使用しました。これにより、クエリレベルでゲート(アクセス制限)を適用できるようになりました。

検索結果は以下のルールに従います:

  • ブログ記事は公開。
  • オンデマンド動画は制限あり。
  • コースはLearnDash経由で制限。
  • ストア製品は公開。

子テーマにカスタムRESTルートを構築しました。検索の安定性を確保するため、スニペットプラグインの使用は避けました。

エンジニアリングの重要詳細

• サーバーサイドでのゲート管理:JavaScriptを使用して結果を隠してはいけません。ブラウザ上で結果を隠したとしても、データはネットワークレスポンスの中に残っています。ユーザーはDevToolsでそれを見ることができてしまいます。サイトから送信される前に、サーバー側でデータをフィルタリングする必要があります。

• キャッシュ管理:検索結果をキャッシュすると、会員専用のプライベートな結果を一般ユーザーに提供してしまう可能性があります。情報漏洩を防ぐため、検索用のRESTルートをページキャッシュから除外してください。

• 段階的な機能縮退(Graceful Degradation):Relevanssiのようなサードパーティ製プラグインを呼び出す際は、ガード(保護処理)を使用してください。プラグインが失敗した場合でも、サイトをクラッシュさせるのではなく、WordPress標準の検索機能にフォールバックするようにします。

• パフォーマンス:デバウンス関数(250ms)とAbortControllerを使用します。これにより、キー入力のたびにブラウザが新しいリクエストを送信するのを防ぎます。また、古いリクエストをキャンセルすることで、古いデータが新しい結果を上書きするのを防ぎます。

• セキュリティ:innerHTMLを使用する前に、必ず文字列をエスケープしてください。これにより、悪意のある投稿タイトルによるXSS攻撃を防ぐことができます。

モバイルでの教訓

ページビルダーがモバイルメニューの中に検索ボタンを飲み込んでしまい、苦労しました。多くのCSS修正を試みましたが、うまくいきませんでした。

解決策は単純でした。テーマと戦うのをやめることです。ボタンをメニューの中に入れるのではなく、ヘッダーに別の要素として注入しました。もしコンポーネントが変更を拒むようなら、その中に配置するのではなく、その横に配置してください。

ベストプラクティスのまとめ:

  • アクセス制御はサーバー側で強制する。
  • 検索エンドポイントをキャッシュから除外する。
  • スムーズなUXのためにデバウンスとAbortControllerを使用する。
  • XSSを防ぐためにすべてのAPIデータをエスケープする。
  • 制御しにくいテーマのコンテナの外側に要素を配置する。

出典: https://dev.to/highcenburg/building-a-search-modal-for-a-membership-gated-wordpress-site-b92