Tracking Zero-Result Searches

A search box that returns nothing is a reader telling you exactly what is missing. "sso", "rate limit 429", "delete account", "terraform provider" — each zero-result query is a question the documentation could not answer, phrased in the reader's own words. Static sites often have search without any analytics on it, because the search runs entirely in the browser with Pagefind or Lunr and nothing reaches a server. That leaves the most useful content-planning data a site produces on the floor.

This guide records zero-result and low-engagement searches on a static site — with Pagefind in the browser and with a search server — without collecting personal data, and turns the data into a weekly report that drives synonyms, content fixes and new pages. It is part of Search for Static Sites. The numbers come from a 2,300-page product documentation site with about 38,000 searches a week.

Prerequisites

  • A search UI you control (Pagefind UI or a custom component, Typesense, Algolia or similar).
  • An analytics tool with custom events (Plausible, Umami, PostHog, GA4) or a small edge function with somewhere to write (Cloudflare Workers Analytics Engine, D1 or a log drain).
  • A privacy review of what will be stored.

What to Record

Three events answer most questions:

  • search — the normalized query, number of results, and the section the reader was in.
  • search_click — the query and the position of the clicked result.
  • search_abandon — a query with results where the reader closed search without clicking within 10 seconds.

Zero-result queries are search events with results = 0. Abandoned searches with results are the quieter signal: the results existed but did not look right.

Normalizing and Protecting Queries

Readers type personal data into search boxes: email addresses, customer IDs, API keys pasted by mistake. Normalize and filter before anything leaves the browser:

function cleanQuery(q) {
  const s = q.normalize('NFKC').toLowerCase().trim().replace(/\s+/g, ' ').slice(0, 80);
  if (/@/.test(s)) return '[email]';
  if (/\b[0-9a-f]{24,}\b|\b\d{7,}\b|sk_[a-z0-9]+|ghp_[a-z0-9]+/i.test(s)) return '[redacted]';
  return s;
}

Also debounce: log a query only when the reader pauses for 1.5 seconds or presses Enter, not on every keystroke, or "t", "te", "ter" and "terr" fill the report. No user identifiers are attached; the analytics tool already aggregates by page and date.

Search logging pipeline with privacy filtering A reader types a query. The UI waits for a pause or Enter, normalizes and truncates the query, and redacts emails, long numbers and token patterns. It records the result count and section and sends a search event without user identifiers. Events are aggregated weekly into top zero-result and abandoned queries with trends. From keystroke to weekly report Typed query in search dialog Debounce pause or Enter Normalize + redact in the browser Event query, count, section Weekly report top 20 with trends
Redaction happens in the browser, so personal data never reaches the analytics tool at all.

Recording With Pagefind

Pagefind UI does not emit events itself, but the search result is available when using the JavaScript API directly, and the UI's input can be observed. With a small custom UI built on pagefind.search():

const pagefind = await import('/pagefind/pagefind.js');
let timer;
input.addEventListener('input', () => {
  clearTimeout(timer);
  timer = setTimeout(async () => {
    const q = input.value;
    if (q.trim().length < 2) return;
    const search = await pagefind.debouncedSearch(q);
    if (!search) return;
    render(search.results);
    track('search', { q: cleanQuery(q), results: search.results.length, section: location.pathname.split('/')[1] || 'home' });
  }, 1500);
});

track sends a Plausible custom event here (plausible('search', { props })); any analytics tool with custom properties works. Clicks call track('search_click', { q, position }) from the result link handler.

Recording With a Search Server

With Typesense, Algolia or Meilisearch, the server already sees every query. Typesense's analytics rules can aggregate popular queries and queries with no hits into collections automatically; Algolia's analytics dashboard reports "no results" queries directly. Server-side logs are complete but mix in bots and monitoring probes, so filter by user agent and exclude queries from the uptime checker. The client-side event approach above still helps for abandonment, which the server cannot see.

Turning Data Into Fixes

The report groups zero-result queries by normalized text, shows the count for the last seven days and the previous seven, and links to the search page with the query pre-filled. Each week, a writer triages the top 20 into one of five fixes:

FixExample queryAction
Synonym"sso"add synonym set: sso, single sign-on, saml
Naming mismatch"workspace"product renamed "workspace" to "project"; add the old name to the page
Missing content"terraform provider"write a new guide
Typo not tolerated"webhok"enable or tune typo tolerance
Out of scope"pricing"add a pointer to the pricing page in search empty state

Most weekly fixes took minutes: adding a synonym, or a sentence mentioning an old name on an existing page. New content went into the docs backlog with the search volume as evidence.

Zero-result queries by type of fix over twelve weeks Horizontal bars of distinct top-20 zero-result queries over twelve weeks, grouped by fix. Synonym added 71. Naming mismatch fixed on an existing page 48. New content written 29. Typo tolerance tuned 22. Out-of-scope pointer added 14. How 12 weeks of top queries were resolved Synonym added 71 Old name added to page 48 New content written 29 Typo tolerance tuned 22 Pointer in empty state 14
184 distinct queries reached a weekly top 20 in the period; each was resolved at most once.

Improving the Empty State

Some zero-result searches will always happen. The empty state decides what readers do next. On this site, it now shows the query back, suggests one or two corrections from a small edit-distance check against page titles, links to the three most-visited guides in the current section, and offers a "search the community forum" link with the query pre-filled. Readers who hit the empty state clicked something on the page 44% of the time, up from 12% with the previous plain "No results" message.

Reading the Report Well

A few patterns in the data are easy to misread. Seasonal spikes — a query for a feature announced in a blog post, searched heavily for a week — look urgent and fade on their own; the week-over-week trend column separates them from steady demand. Queries in other languages on an English-only site are a signal for localization rather than content, and on this site they justified translating the twenty most-read pages into German first, as described in Internationalization for Static Sites. Very short queries ("api", "sdk") often return many results rather than none, but show high abandonment: the fix there is better ranking or a curated landing page, not more content.

Abandonment deserves its own weekly look. A query with results that readers consistently abandon usually means the right page exists but its title or excerpt does not look like the answer. Rewriting titles and the first sentence of the most-abandoned targets moved click-through on those queries from 31% to 57% on this site — often a faster win than writing anything new.

Finally, share the report beyond the docs team. Product managers found the zero-result list useful as evidence of features readers expected; support used it to spot confusion before tickets arrived. A two-line summary in the team channel each Monday — the top three new zero-result queries and what was done about last week's — kept the habit going.

Measured Impact

MeasureBefore trackingAfter 12 weeks of weekly fixes
Zero-result rate11.8%5.3%
Searches ending in a result click57%68%
Clicks from the empty state12%44%
New guides written from search demand—29
Support tickets tagged "couldn't find in docs" per month14096
Weekly zero-result search rate after tracking began Vertical bars of the weekly zero-result rate. Week 1 11.8 percent, week 3 9.6 percent, week 6 7.4 percent, week 9 6.1 percent and week 12 5.3 percent. Zero-result rate over twelve weeks 11.8% Week 1 9.6% Week 3 7.4% Week 6 6.1% Week 9 5.3% Week 12
Share of logged searches with no results; the weekly volume stayed around 38,000 searches.

Pitfalls & Rollback

  • Logging every keystroke. Debounce, or the report fills with prefixes.
  • Storing raw queries. Redact emails, IDs and tokens in the browser.
  • Counting bots. Server-side logs include crawlers and probes; filter them.
  • Treating the report as a dashboard. It only helps if someone triages it weekly.
  • Rollback: the tracking is a few lines in the search UI; removing the track calls stops collection immediately, and stored aggregates can be deleted.

Conclusion

Zero-result searches are the cheapest content research a documentation team can get. Record them from the search UI with privacy filtering, review the top queries weekly, and fix them with synonyms, renamed terms, new pages and a helpful empty state. On this site twelve weeks of that halved the zero-result rate and measurably reduced "couldn't find it" support tickets.

FAQ

Why track zero-result searches?

They are direct evidence of what readers expected to find and could not. Each recurring zero-result query points at a missing page, a missing synonym, a naming mismatch between the product and the docs, or a search configuration problem, and fixing the top few usually improves search success noticeably.

How can a static site record searches without a backend?

Send an event from the search UI to an analytics tool that supports custom events, or to a small edge function that writes to a log or database. Only the query text, result count and page context are needed.

What about privacy?

Search queries can contain personal data such as email addresses or account IDs that readers paste. Normalize and truncate queries, drop anything matching email or long number patterns, never attach user identifiers, aggregate before storing where possible, and mention search logging in the privacy notice.

How often should the report be reviewed?

Weekly worked well on the site measured here. The top 20 zero-result queries by count, with their trend, fit in a short review, and most fixes, such as adding a synonym or a sentence to an existing page, take minutes.

Filed underHow-tosPagefind