Routing
{% set _routing = prefs.use_tor if prefs.use_tor in ('tor', 'tor_fallback', 'direct') else ('tor' if prefs.use_tor else 'direct') %}
When using Tor, your real IP is never sent to any instance. DNS also resolves through Tor. Tor with fallback falls back to direct if Tor is unreachable or times out (configure the timeout below) — captchas and rate-limits are per-instance problems, not Tor failures, so they never trigger a fallback. Tor only never falls back regardless of timeout.
{% set _rm = prefs.get('reader_mode', 'both') %}
Fetches pages through a fresh Tor circuit and renders them in a clean reader view — your IP never reaches the target site. Both keeps the direct link for when you need the full page. Reader only routes every click through Tor. Only available when routing through Tor.
Adds a jina badge to each result that opens the page via r.jina.ai — clean markdown extraction, no cookies, no JS. Works regardless of Tor routing.
Adds an archive badge to each result linking to web.archive.org — lets you read a cached snapshot without hitting the live site. Useful for paywalls, dead links, and avoiding tracking. Always opens as a direct connection (Wayback Machine blocks Tor exit nodes).
{% set _jr = prefs.get('jina_routing', 'direct') %}
Applies to both Jina reader links and AI content fetching. Direct is usually fine — Jina fetches the target page on their own infrastructure, so your IP never reaches the site either way.
Without a key, Jina rate-limits requests and may return 403. Free keys available at jina.ai — 1M tokens/month on the free tier. Never stored in profiles or personalities.
{% set _tp = prefs.get('thumbnail_proxy', 'direct') %}
Controls how image and video thumbnails are fetched. SearXNG always proxies the actual image CDN, so Fast only exposes your IP to the SearXNG instance — not to the image source. Max privacy hides your IP from the instance too but adds Tor latency to every thumbnail.
{% set _mr = prefs.get('map_routing', 'tor') %}
Controls how map geocoding (place search, address lookup) and directions are routed. Independent of the main search routing above.
{% set _mtr = prefs.get('map_tile_routing', 'tor') %}
Tiles are always fetched server-side — the tile provider never sees your browser IP. This controls whether the server itself uses Tor when fetching them. Tiles are cached by the browser after first load so subsequent views are instant regardless of this setting.
{% set _air = prefs.get('ai_routing', 'direct') %}
Applies to AI summary requests. AI providers often block Tor exit IPs — your API key already identifies your account regardless of IP. Local Ollama always connects directly.
{% set _rrr = prefs.get('ai_rerank_routing', 'direct') %}
{% set _show_rr_routing = prefs.get('ai_reranking') and not prefs.get('ai_rerank_use_search_ai', True) %}
Routing for the dedicated reranker provider. Reranking APIs often block Tor exit IPs. Local Ollama always connects directly.
Map
{% set _mtp = prefs.get('map_tile_provider', 'openstreetmap') %}
{% set _rp = prefs.get('route_provider', 'osrm_public') %}
Route requests go through your routing setting above (Tor / direct). The public OSRM instance is run by the OSRM project and has no usage limits for reasonable traffic.
{% set _mom = prefs.get('map_offline_method', 'none') %}
{% set _mob = prefs.get('map_offline_behavior', 'hybrid') %}
Offline tiles let the map display without a network connection. Service Worker caching works with any tile provider above. PMTiles loads a single self-contained archive — good for frequently visited areas.
AI Summary
Optional. When configured, a "✦ Ask AI" button appears on results. Your query and top results are sent to the provider on demand — never automatically.
Saves the current AI settings (provider, model, routing, prompt, avatars) as a named preset. Your API key is never included.
When configured, pressing "✦ Ask AI" on the Images tab generates an image: the AI writes an optimised prompt from your query, then sends it to the image generation provider below.
Appearance
Saves the entire appearance section — colors, font, background, title, favicon.
Colorways swap the palette only — title, font, and background are left as-is. Use the saved themes above to apply a full look.
{% set _sr = prefs.get('streaming_results', 'off') %}
{% set _li = appearance.get('loading_indicator', 'bar') %}
Timed mode fills the bar linearly over the configured request timeout, so it roughly reflects actual wait time.
One line per quip. They cycle while search results load. Leave blank to use the built-in defaults.
{% set _ct_style = appearance.get('christmas_tree_style', 'dots') %}
{% set color_labels = [
("--bg", "Background"),
("--surface", "Surface"),
("--border", "Border"),
("--text", "Text"),
("--muted", "Muted text"),
("--title", "Title / brand"),
("--accent", "Accent"),
("--accent-dim", "Accent (dim)"),
("--visited", "Visited links"),
("--url", "URL green"),
("--error", "Error red"),
("--engine", "Engine badge bg"),
("--engine-text", "Engine badge text"),
] %}
{% for var, label in color_labels %}
{{ label }}
{% endfor %}
Search Preferences
Saves engines, priority sources, ranking and scoring settings as a named preset.
One engine per line. When engine ranking is on, order matters — engines listed first score higher.
Add [category] after an engine name to use it only for that tab —
e.g. youtube [videos], bandcamp [music], openstreetmap [map].
Without a rider, common engines (bing, google, duckduckgo, brave, qwant) are automatically
remapped to their category variants for news; for images/videos/music/files/map tabs,
only engines already native to that category are used — everything else is dropped so
SearXNG falls back to whatever specialist engines your instance has enabled.
Results from these engines are always hidden. One engine name per line. Use exact names as shown in the tree (e.g. lemmy comments, arxiv).
{% set _sr = prefs.get('streaming_results', 'off') %}
Requires multi-instance search (2+ instances). In live mode, results appear card by card as each instance reports in.
BCP-47 tag like en-US or fr-FR. Comma-separate multiple languages to search all of them in parallel and merge results — e.g. en-US, fr-FR. Each language uses its own Tor circuit and instance. Use all for no language preference. Note: Tor exit node GeoIP may still influence some backend engines regardless of this setting.
{% set _all_cats = [("all","All"),("general","General"),("news","News"),("images","Images"),("videos","Videos"),("map","Map"),("music","Music"),("science","Science"),("it","IT"),("files","Files"),("social media","Social")] %}
{% set _tc = prefs.tab_categories if prefs.tab_categories else ["all","general","news","images","videos","map","music","science","it","files","social media"] %}
Drag to reorder. Uncheck to hide a tab from the results page.
Which tab is active when you submit a fresh search from the home page. Switching tabs on the results page always overrides this.
DeArrow crowdsources better video titles (no clickbait) and thumbnail timestamps (no faces/text overlays). When enabled, video results are enriched after loading using the same routing setting as your searches.
One domain per line. Results from these domains are always pushed to the top of the page, in the order listed. Subdomains match automatically — wikipedia.org matches en.wikipedia.org. A toggle on the results page lets you turn this off per-search.
Maximum results boosted per source. With cap 1 and two sources, up to 1 result from each source is promoted — sources appear in the order listed above. Default is 1.
One domain per line. Results from these domains are pushed to the bottom of every search, after all other ranking. Subdomains match automatically. Useful for filtering out social media, forums, or any domain that consistently clutters your results.
{% set dec = prefs.get('demote_except_categories', ['social media']) %}
{% for cv, cl in [('all','All'),('general','General'),('news','News'),('images','Images'),('videos','Videos'),('map','Map'),('music','Music'),('science','Science'),('it','IT'),('files','Files'),('social media','Social')] %}
{% endfor %}
Demotion is skipped entirely when searching in these categories. Social is on by default so reddit.com etc. still show up normally when you're explicitly browsing the social tab.
Fuzzy mode merges results that are the same page but differ only by www., http/https, or tracking parameters like utm_source, fbclid, etc. Disable if you want to see every URL variant as a separate result.
Engines listed first in your engine list score higher. When off, all engines contribute equally to consensus scoring.
Each search engine that found a result scores points for it (rank-weighted if engine ranking is on, flat 1 if off). Each additional SearXNG instance that returned the result also adds 1 point — so a result agreed on by 3 instances and 2 engines scores higher than one found by 1 instance and 2 engines.
Ranks results by how closely they match your query terms. Title matches count 3× more than snippet matches. Works with all other ranking options.
{% if not semantic_available %}
~500 MB download (PyTorch + transformers). Scrambler will need a restart after install.
{% else %}
Reranks results by semantic similarity to your query using a local embedding model. Applied after all other ranking passes.
{% endif %}
Any sentence-transformers model or Hugging Face model ID. Changing the model downloads it on next search. Fast: MiniLM-L6 (~80 MB). Best: mpnet-base (~420 MB).
When a query contains temporal signals (today, latest, breaking, a year like 2025…) Scrambler blends recency into ranking so recent results appear higher. Only affects queries that read as time-sensitive. Undated results are not penalised — they land between recent and old results.
Caches identical queries. TTL is 30 s for news/temporal queries, 2 min for general queries, 5 min for reference/definition queries. Repeated searches and back-button navigations are instant. Disable to always hit instances fresh.
{% set mi_max = [instance_count, 1] | max %}
{% set mi_val = [[prefs.multi_instance, 1] | max, mi_max] | min %}
Queries run in parallel across instances. Each operator sees your query as a Tor exit IP, not your real IP.
Weighted selection tracks each instance's average response time and picks faster ones more often. Disable for purely random routing.
{% set efl_max = [instance_count, 1] | max %}
{% set efl_val = [[prefs.get('engine_failover_limit', 3), 0] | max, efl_max] | min %}
How many additional instances to try when a search fails. Applies in two situations: (1) if all initial concurrent instances fail, this many more are tried one at a time with the full engine list; (2) after the first success, this many more instances are tried for any engines that returned no results, sending only the missing engines each time. Set to 0 to disable all fallback. Maximum is capped to your instance count ({{ instance_count }}).
Total time allowed for the engine failover phase. With Tor circuits taking 8–13 s each, 60 s allows ~4–7 attempts. Set to 0 for no time limit — failover runs until all engines are accounted for or the instance list is exhausted. Less relevant in live mode where results stream in as they arrive. Default 60 s.