diff --git a/error.html b/error.html
index 350f0625..914a19c2 100644
--- a/error.html
+++ b/error.html
@@ -47,6 +47,8 @@
background: var(--panel); border: 1px solid var(--line); color: var(--acid);
font-family: ui-monospace, monospace; font-size: 12.5px; text-decoration: none; cursor: pointer; }
.suggest a:hover { border-color: rgb(from var(--acid) r g b / .55); filter: brightness(1.05); }
+ .suggest a.search { font-family: inherit; color: var(--ink); }
+ .suggest a.search:hover { color: var(--acid); }
.actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 1.3rem; }
.btn { font-family: inherit; font-size: 13.5px; padding: 9px 16px; border-radius: 9px;
border: 1px solid var(--line); background: var(--panel2); color: var(--ink);
@@ -270,13 +272,16 @@
actionsBox.appendChild(b);
}
- // "Did you mean" — two sources, merged into one row:
+ // "Did you mean" — two sources, merged into one row, plus a search chip:
// • BCNR warm shared index (Levenshtein ≤ 2, same TLD) — for a BCDN name
// typo like "games.x" → "game.x". Local index; works offline.
// • ICANN alternative-TLD swaps + history base-name matches — a DNS
// failure on my.mynymbox.com surfaces my.mynymbox.io, .net, .org, …,
// and any related host the user has visited. Local too.
- // Clicking a suggestion retries at that host, preserving the original path.
+ // • A trailing "Search ''" chip that defers to the default
+ // search engine when none of the URL alternatives looks right.
+ // Clicking a URL chip retries at that host (keeps the original path);
+ // clicking the search chip opens a search for the host text.
if ((kind === "name-not-registered" || kind === "name-unreachable") && host) {
let origPath = "/";
try { const u = new URL(url); origPath = u.pathname + u.search + u.hash; } catch {}
@@ -292,7 +297,6 @@
seen.add(name); matches.push(name);
if (matches.length >= 4) break;
}
- if (!matches.length) return;
const row = $("suggestRow");
for (const name of matches) {
const a = el("a", null, name);
@@ -303,6 +307,23 @@
});
row.appendChild(a);
}
+ // Search chip. Shown whenever we have a host, even when no URL match
+ // surfaced — "search for it on your default engine" is the universal
+ // fallback for a DNS miss.
+ const s = el("a", "search", "🔎 Search '" + host + "'");
+ s.href = "#";
+ s.title = "Open your default search engine with this as the query";
+ s.addEventListener("click", (ev) => {
+ ev.preventDefault();
+ window.errorpage.searchFor(host);
+ });
+ row.appendChild(s);
+ // Replace the row's "Did you mean" label with a softer one when the
+ // only chip is the search fallback — nothing to actually suggest.
+ if (!matches.length) {
+ const lbl = $("suggest").querySelector(".lbl");
+ if (lbl) lbl.textContent = "Not sure what you were after?";
+ }
$("suggest").hidden = false;
}).catch(() => {});
}
diff --git a/package.json b/package.json
index 2ef56bf1..43458281 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "theseus-navigator",
- "version": "0.3.122",
+ "version": "0.3.123",
"license": "MPL-2.0",
"description": "Theseus Navigator — a browser that follows the thread. By Silent Mode, a Deviant project.",
"author": "Silent Mode",