SearXNGをブラウザの既定の検索エンジンにする
自分のSearXNGを検索窓にする手順。base_urlとOpenSearchの関係、Firefox、Chromium、Android、iOSそれぞれの登録方法、日本語結果の固定、端末間での設定共有まで。
SearXNG を既定の検索エンジンにする
VPS で動いている SearXNG を、アドレスバーに直接打ち込む検索エンジンにするには、作業が2つあります。インスタンスが OpenSearch の記述ファイルを正しい絶対 URL で配れる状態にすること、そしてブラウザごとに検索エンジンとして登録することです。自動で登録できないブラウザが多いので、その場合は %s を含む検索 URL を手で入力します。iOS の Safari はカスタムの検索エンジンを追加できないため、ここだけは別の方法になります。
インスタンスがまだない人は先に VPS に SearXNG を自分で立てる手順 を終わらせてください。この記事は、HTTPS で外から開ける SearXNG が既に1台ある状態から始めます。
この記事で触れる設定キーとファイルの場所は、2026年9月時点の公式ドキュメント(2026.9 系)で確認したものです。SearXNG はリリースが速く、設定ファイルの置き場所は導入方法によっても違います。自分が動かしているバージョンのドキュメントで名前とパスを確認してから編集してください。コンテナで入れた場合、現在のドキュメントは core-config/settings.yml を編集する形になっています。
なぜ自分のインスタンスはブラウザの検索エンジン一覧に出てこないのか
ブラウザが「このサイトを検索エンジンとして追加できます」と気付く仕組みは OpenSearch(検索エンジンの自己記述フォーマット)です。SearXNG はページの <head> に次の行を出します。
<link title="{{ instance_name }}" type="application/opensearchdescription+xml" rel="search" href="{{ opensearch_url }}">ブラウザはこの行をたどって /opensearch.xml を取りに行き、その中の検索 URL を読んで登録します。そして SearXNG のこのテンプレートは、絶対 URL を組み立てて書き出します。つまり「インスタンスが自分自身をどの URL だと思っているか」がそのままブラウザに渡ります。ここが噛み合わないと、ブラウザは登録できないか、登録できても検索が通りません。
設定 server.base_url の既定値は false です。この状態では絶対 URL はリクエストのヘッダから組み立てられます。リバースプロキシが Host と X-Forwarded-Proto を渡していなければ、http://127.0.0.1:8888/... のような内部向けの URL が記述ファイルに入ります。ブラウザはその URL に検索を投げるので、何も返ってきません。推測せずに、実際に配られているものを見てください。
curl -s https://search.example.com/opensearch.xml出てきた XML の <Url ...> にある template 属性を読みます。自分の HTTPS の URL がそのまま入っていれば正常です。http:// で始まっていたり、ホスト名が内部のものになっていたら、そこが原因です。ドキュメントによれば base_url は「SearXNG を配置した base URL。正しい inbound link を作るために使われる」設定で、環境変数 $SEARXNG_BASE_URL でも渡せます。
server:
base_url: "https://search.example.com/"編集したら再起動して、もう一度 curl で同じ行を確認します。コンテナなら docker compose restart です。値を書いたから直ったと考えず、XML の文字列が変わったことを目で確かめてください。
docker compose restart
curl -s https://search.example.com/opensearch.xmlこの XML には、もう1つ大事な要素が入ります。サジェスト(入力候補)用の URL です。search.autocomplete が有効なとき、application/x-suggestions+json を返す /autocompleter への URL が記述ファイルに含まれます。後半のレート制限の話はここに戻ってきます。
もう1点。server.method を "POST" にしているインスタンスでは、OpenSearch の記述が q を POST のパラメータとして書き出します。ブラウザの手動登録は GET の URL しか受け取れませんが、ドキュメントには / と /search はどちらも GET と POST の両方を受けると書かれているので、手で登録する %s 付きの URL は method の値に関係なく動きます。
Firefox(デスクトップ)に登録する
Firefox 140 以降は、設定画面から自分で検索エンジンを追加できます。それより前のバージョンには追加用の UI がなく、拡張機能か OpenSearch の自動検出に頼るしかありませんでした。
- メニューから Settings を開き、左の Search を選びます。
- Search Shortcuts の表の下にある Add を押します。
- 名前に SearXNG など好きな文字列を入れます。
- URL には検索用の URL を入れ、キーワードの位置に
%sを書きます。
URL はこの形です。キーワードのショートカット(例えば s)も同時に設定しておくと、既定のエンジンを変えずにアドレスバーで s 東京 天気 と打てます。
https://search.example.com/search?q=%sOpenSearch 経由で入れたい場合は、インスタンスの検索フォームを右クリックして Add Search Engine を選びます。日本語 UI では表記が違うので、画面に出ている文言を読んでください。この経路で入ったエンジンにはサジェスト用の URL も付きます。どちらの経路でも、既定にするのは Settings の Search で Default Search Engine を切り替える操作です。
自動検出が出てこないときは、原因はほぼ base_url か証明書です。前の節の curl の出力を先に直してください。HTTPS が有効でも、証明書がブラウザに信頼されていなければ同じように出てきません。
Chromium 系(Chrome, Edge, Brave, Vivaldi)に手で追加する
Chromium 系は自動検出に期待しないほうが早いです。chrome://settings/searchEngines(Edge は edge://settings/searchEngines)を開き、サイト内検索の追加から自分で登録します。入力する項目は名前、ショートカット、URL の3つで、URL の書き方は Firefox と同じです。
https://search.example.com/search?q=%s追加した項目の右端のメニューから、既定の検索エンジンに設定できます。この画面の見出しやボタンの文言はバージョンごとに変わるので、記事の文言ではなく画面の文言に従ってください。
Chromium 系は、OpenSearch を出しているサイトで実際に検索すると、そのサイトを一覧に記録することもあります。ただし記録されるだけで既定にはならないので、結局この画面を開くことになります。手で入れたほうが確実です。
Android の Firefox と Chrome は同じではない
ここは端末ごとに結果が変わるところなので、期待値を先に書きます。Android の Firefox は自分で追加できます。Android の Chrome は手で追加する UI がありません。
Firefox for Android では、アドレスバーの検索エンジンのアイコンをタップし、下に出る Search settings から Manage alternative search engines に進みます。Firefox 140 以降は拡張機能なしでここから追加できます。URL の書き方はデスクトップと同じで、クエリの位置を %s にします。追加したあと、既定のエンジンとして選び直すのを忘れないでください。追加しただけでは検索窓は前のエンジンを使い続けます。
Chrome for Android には、検索エンジンを手で入力する画面がありません。OpenSearch の自動検出に頼ることになり、その自動検出がデスクトップほど素直に動かないことは Chromium 側の課題として長く残っています(issue 40353868)。現実的な選択肢は2つです。Android では Firefox を使って自分のインスタンスを既定にするか、Chrome は既定のまま残して、SearXNG をホーム画面のショートカットから開くかです。後者は検索窓の置き換えにはなりません。そこを曖昧にすると、あとで「Chrome の検索窓が SearXNG にならない」と悩むことになります。
iOS の Safari にカスタムの検索エンジンは追加できない
iOS の Safari は、Apple が用意した一覧から選ぶ形式です。自分の URL を登録する方法はありません。プロファイルでも拡張でもなく、単に機能が存在しません。回避策として現実的なのは次の2つです。
- Firefox for iOS を使う。Settings から Search を開き、Quick-Search Engines の一覧の下にある Add Search Engine をタップし、Title に名前、URL に
%sを含む検索 URL を入れます。そのうえで既定のエンジンとして選びます。 - Safari は既定のまま使い、ショートカット.app で「テキストを入力」してから
https://search.example.com/search?q=にその文字列をつないだ URL を開くショートカットを作り、ホーム画面か共有シートから呼び出します。検索窓そのものにはなりませんが、ホーム画面の1タップからは自分のインスタンスで検索できます。
iPhone の Safari を SearXNG にしたい、という要望にそのまま応える方法はありません。どちらの回避策を取るかは、Safari を諦めるかタップ1回を諦めるかの選択です。
日本語の結果を既定にする
既定のエンジンにしても結果が英語圏中心のままだと使い続けられません。SearXNG では言語の指定が3つの層に分かれていて、混ぜて考えると迷子になります。
インスタンス全体の既定は search.default_lang です。既定値は auto で、この場合はブラウザの情報から推測されます。日本語で固定するなら、searx/sxng_locales.py に載っているコードを使います。このファイルには ('ja', '日本語', '', 'Japanese', ...) と ('ja-JP', '日本語', '日本', 'Japanese', ...) の2行があります。ja は言語だけの指定で、ja-JP は地域まで含んだ指定です。地域を含めたほうが、対応しているエンジンで日本向けの結果が返ります。
search:
default_lang: "ja-JP"
ui:
default_locale: "ja"ui.default_locale は画面の言語です。ドキュメントには「SearXNG interface language. If blank, the locale is detected by using the browser language」とあります。これは結果の言語には関係しません。UI が日本語なのに結果が英語だ、という状態はこの2つを混同したときに起きます。逆に default_lang だけ設定して UI が英語のままでも、結果は日本語で返ります。
検索ごとに切り替えたいときは、検索語の前に :ja を付けます。ドキュメントの検索構文の項に :fr !wp Wau Holland という例があるとおり、: に続けて言語コードを書く形式です。エンジンを絞る ! と組み合わせられます。
ブラウザに登録する URL 側で固定する方法もあります。検索 API のパラメータに language があるので、登録する URL をこうします。
https://search.example.com/search?q=%s&language=ja-JPこれは cookie に依存しないので、シークレットウィンドウでも新しい端末でも同じ挙動になります。ただし SearXNG 自身が設定画面で注意している点として、検索 URL に設定を書き込むと、クリック先のサイトに情報が漏れる分だけプライバシーが下がります。原文では「Note: specifying custom settings in the search URL can reduce privacy by leaking data to the clicked result sites.」です。言語1つなら実害は小さいですが、URL に設定を並べ始める前にこの注意を思い出してください。どのエンジンを日本語検索で使うかは 有効にすべきエンジンと切るべきエンジン 側の判断になります。
ラップトップとスマホで設定をそろえる
SearXNG にはアカウントがありません。設定はサーバではなく、ブラウザの cookie に保存されます。だから端末を変えると設定は引き継がれず、ラップトップで日本語に直した設定はスマホには何の影響もありません。
持ち運ぶ仕組みは用意されています。設定ページの Cookies タブに、次の2つが並びます。「Search URL of the currently saved preferences」と「URL to restore your preferences in another browser」です。後者の説明文はこうです。「A URL containing your preferences. This URL can be used to restore your settings on a different device.」
同じ画面には Copy preferences hash というボタンと、「Insert copied preferences hash (without URL) to restore」と書かれた Preferences hash の入力欄があります。手順はこうなります。ラップトップの設定ページでハッシュをコピーし、スマホで同じインスタンスの設定ページを開いて、その欄に貼って保存します。URL ごと送ってもかまいませんが、貼り付け欄は URL なしのハッシュを期待しているので、URL を送った場合はハッシュの部分だけを使ってください。
注意点は cookie であることから全部出てきます。プライベートウィンドウでは残りません。cookie を消す拡張やブラウザの掃除機能は、この設定も消します。設定を変えたら新しいハッシュが必要になるので、共有はその都度やり直しです。頻繁に変えるものは、前の節のように URL パラメータで固定してしまったほうが楽です。
既定にすると検索の回数が跳ね上がる
ここが運用で一番効いてくる話です。検索窓にした瞬間から、あなたのインスタンスへのリクエストは「検索した回数」ではなくなります。
OpenSearch 経由で登録されたエンジンには、サジェスト用の URL が入っています。行き先は /autocompleter です。既定の設定は autocomplete: "duckduckgo" と autocomplete_min: 4 なので、4文字目から入力のたびに候補のリクエストが飛び、インスタンスはそれを上流(既定では DuckDuckGo)に問い合わせます。1回の検索で /search が1回、その前に候補が何回か、という形になります。手で %s の URL を登録した場合はサジェスト用の URL が登録されないので候補は出ませんが、そのぶん挙動は静かです。
実際に何が飛んでいるかはログで数えられます。
sudo grep autocompleter /var/log/nginx/access.log | tail -n 20この増分が、自分で自分のレート制限を踏む理由です。SearXNG 側の limiter が 429 を返すか、上流のエンジンが captcha を出すか、どちらかで詰まります。429 が出るようになったときの切り分けは 429 Too Many Requests が出る原因と直し方 にまとめてあり、limiter の閾値そのものを触るなら limiter.toml と Valkey の設定 を見てください。上流から captcha が返り始めた場合は エンジンの captcha エラーを解消する手順 が該当します。
候補の量を減らすだけなら、インスタンス側で2つ調整できます。search.autocomplete を空にすると候補機能そのものが止まります。autocomplete_min を大きくすると、候補が出始める文字数が増えます。
search:
autocomplete: ""
autocomplete_min: 6インスタンスを自分だけで使っているなら、limiter を緩める判断もありえます。外から誰でも開ける状態なら話は別で、既定の検索エンジンにするということは、その URL をあなたのブラウザが常に叩き続けるという意味です。そこに他人のトラフィックが混ざると、どちらが 429 の原因か分からなくなります。公開したまま使うなら 公開 SearXNG インスタンスを固める手順 を先に通し、そもそも公開せずに済ませたいなら ポートを開けずに Cloudflare Tunnel で公開する方法 のほうが合っています。
設定が効いたかどうかの確認リスト
作業が終わったら、次の順で確認します。上から順に見ることで、どこで壊れているかが切り分けられます。
curl -s https://search.example.com/opensearch.xmlのtemplateに自分の HTTPS の URL が入っている。- ブラウザのアドレスバーから検索して、結果ページの URL が自分のインスタンスになっている。
- 結果が日本語で返っている。返っていなければ
default_langか URL のlanguageを見る。 - スマホでも同じ結果になる。ならなければ設定のハッシュを貼り直す。
4つ全部が通れば、検索窓は自分のインスタンスに置き換わっています。あとは 429 が出ないかどうかを1週間ほど見て、出るならエンジンの数と候補の設定を削ってください。
FAQ
ブラウザの検索エンジン一覧に自分の SearXNG が出てきません。なぜですか
ブラウザは <head> の rel="search" の行から OpenSearch の記述ファイルを読み、その中の絶対 URL を登録します。server.base_url が false のままだと、この絶対 URL はリクエストのヘッダから組み立てられるため、リバースプロキシが Host と X-Forwarded-Proto を渡していないと内部向けの URL になります。curl -s https://search.example.com/opensearch.xml を実行して template 属性の中身を確認してください。http://127.0.0.1:8888/... のようになっていれば base_url を自分の HTTPS の URL に設定して再起動し、同じ curl で文字列が変わったことを確認します。証明書がブラウザに信頼されていない場合も同じように出てきません。
iPhone の Safari を SearXNG にできますか
できません。iOS の Safari は Apple が用意した一覧から選ぶ仕組みで、自分の URL を登録する機能がありません。回避策は2つです。Firefox for iOS の Settings から Search を開き、Add Search Engine で Title と %s を含む URL を登録して既定にするか、Safari はそのままにして、ショートカット.app で入力した文字列を https://search.example.com/search?q= につないで開くショートカットをホーム画面に置くかです。後者は検索窓の置き換えにはなりません。
日本語の結果を既定にしたいのですが、どこを設定しますか
インスタンス全体なら search.default_lang です。既定値は auto で、ja-JP を指定すると地域まで含めた日本向けの指定になります。ja は言語だけの指定です。この2つは searx/sxng_locales.py に載っているコードです。ui.default_locale は画面の表示言語で、結果の言語とは無関係なので、ここだけ ja にしても結果は変わりません。検索ごとに切り替えるなら検索語の前に :ja を付け、ブラウザ側で固定するなら登録 URL を https://search.example.com/search?q=%s&language=ja-JP にします。
ラップトップとスマホで設定が違います。同期できますか
アカウントはなく、設定はブラウザの cookie に入るので自動では同期しません。設定ページの Cookies タブにある Copy preferences hash でハッシュをコピーし、もう一方の端末の同じ画面にある Preferences hash の欄に貼って保存します。この画面には「URL to restore your preferences in another browser」という項目もあり、説明文には別の端末で設定を復元するための URL だと書かれています。cookie なので、プライベートウィンドウや cookie の削除で消えます。消えてほしくない設定は URL のパラメータ側に書いてください。
既定の検索エンジンにしてから 429 が出るようになりました
検索窓にすると、入力のたびに候補のリクエストが /autocompleter に飛びます。既定は autocomplete: "duckduckgo" と autocomplete_min: 4 なので、4文字目から1文字ごとにリクエストが増え、1回の検索が数回のリクエストになります。sudo grep autocompleter /var/log/nginx/access.log | tail -n 20 で実際の量を数えてください。autocomplete を空にするか autocomplete_min を上げると減ります。閾値そのものを調整する場合は limiter の設定を見てください。