Zorto search is DuckDB-backed. A site ships a public .ddb file, the browser loads DuckDB-Wasm on demand, and the search modal queries a search_pages table locally.

How it works #

Buildyour pipeline writes site.ddb
Shipsite.ddb is copied as a static asset
Loadbrowser fetches site.ddb + DuckDB-Wasm
QueryCtrl+K runs SQL against search_pages
Displayranked results render in the modal

Search is a small data app: static files, browser SQL, no search server.

Data artifact #

The current zorto.dev pattern is a checked-in static/data/site.ddb generated by a self-contained uv script. The database includes a search_pages table:

ColumnSource
titlePage or section title
urlPublic URL
descriptionFrontmatter description field
contentMarkdown content stripped to searchable text
title_lowerPrecomputed lowercase title
description_lowerPrecomputed lowercase description
content_lowerPrecomputed lowercase content

Browser runtime #

The built-in theme shows the search button when config.extra.search_database_url is set. On first use, it imports DuckDB-Wasm, fetches the configured .ddb, attaches it read-only, and queries search_pages.

Ranking #

Results are scored by where the match occurs:

Match typePoints
Exact title match100
Title starts with query80
Title contains query60
Description contains query20
Content contains query10

Scores are additive. Results are ordered by score, then title, and limited to the top 10.

The search UI #

The search modal opens with Ctrl+K or Cmd+K. It includes:

  • A one-character minimum query with debounce
  • Keyboard navigation: arrow keys to move, Enter to open, Escape to close
  • Result snippets from description or content with highlighted matches
  • Mobile support via a search button in the header

Further reading #