Browser Start Page — Delivery Notes
Delivery summary for making
tranquil-browser://blank(the new-tab / homepage) a real, theme-matched start page instead of a blank white document. Says what shipped and the two non-obvious traps — the Back button and tab restore — that a naive “just add HTML” would hit.
Status
Implemented and verified in-app (window reload; no full restart needed — this dev package’s lib/*.js hot-reloads).
| Piece | State |
|---|---|
Branded splash + search in resources/home.html | ✅ |
New brand mark (from www-tranquil Logo.svelte) | ✅ |
| DuckDuckGo search + “Search provided by DuckDuckGo” label | ✅ |
| Back button returns to the start page | ✅ |
| Restored blank tabs reload the start page | ✅ |
What it is
tranquil-browser://blank resolves to file://…/resources/home.html, rendered inside the browser’s
isolated <webview>. home.html is now a self-contained page: the Tranquil node/ports mark, a live
clock, a time-of-day greeting, and a search box. Because the webview is a file:// document that
can’t read the theme’s LESS variables, the business dark/light palette is hardcoded as CSS
custom properties, switched with @media (prefers-color-scheme: light) (mirrors history.css).
Search is DuckDuckGo (https://duckduckgo.com/?q=), matching every other search entry point in
the browser (URL bar, right-click, homepage fallback). Input handling: a scheme (https://…) loads
as-is; a domain-like token (github.com) gets https:// prepended; anything else is a DuckDuckGo
query. A muted “Search provided by DuckDuckGo” line sits under the box.
Trap 1 — the Back button (why no history.pushState)
The original blank page ran history.pushState('…','…','tranquil-browser://blank') to show a
friendly URL. That creates a cross-origin fake history entry: after navigating to a real site,
pressing Back tries to load tranquil-browser://blank as a document — but that scheme isn’t
registered at the Electron protocol level, so Back lands on a broken/empty page.
Fix: removed the pushState. The real document (file://…/home.html) stays a normal, reloadable
history entry, so Back cleanly reloads it. To still show the friendly URL, the host does the
mapping: updatePageUrl (tranquil-browser-view.js) detects the home.html document and puts tranquil-browser://blank in the address bar and model.url (the latter keeps getURI()’s
blank-tab dedup working). Key detail — the internal-URL check keys off the destination url, not this.url.val(); the old check got stuck once the bar read tranquil-browser://blank and blocked
every later navigation from updating.
Trap 2 — tab restore went white
On reload, a blank tab deserializes with model.url = 'tranquil-browser://blank'. The view’s content() resolves that through getTranquilBrowserUrl, which only knew history and returned '' for everything else → empty webview → white screen. This was a latent bug: before the page
had content, an empty restore looked identical to an intentionally-blank page.
Fix: add a blank branch to getTranquilBrowserUrl returning the home.html file:// URL —
built from __dirname, not this.resources. getTranquilBrowserUrl is called as params.tranquilBrowser.getTranquilBrowserUrl(url), and in that context this.resources was
wrong/undefined, which still produced white. The __dirname form matches the fresh-open path exactly:
'file://' + require('path').resolve(`${__dirname}/../resources/`) + '/home.html' Files (all in the owned tranquil-browser package)
resources/home.html— the start-page document (markup, hardcoded palette, clock/greeting/search).lib/tranquil-browser-view.js—updatePageUrlfriendly-URL mapping (address bar +model.url).lib/tranquil-browser.js—getTranquilBrowserUrlblank → home.htmlrestore mapping.
Follow-ups (not done)
- The start page is v1 (branded splash + search). Open question, deferred: add favorite/quick-link tiles (a “new-tab dashboard”) vs. keep the splash as-is.
prefers-color-schemefollows the OS appearance, not the in-app business light/dark toggle (same tradeoffhistory.cssmakes). Could be synced by injecting adata-themeinto the webview.- URL-bar autocomplete suggestions still use Bing’s osjson endpoint — separate from search navigation; left as-is.