Skip to content

Universal Search Overhaul — Nominations, Committees, Page Nav, Streaming, Analytics & UX Redesign #269

@ryparker

Description

@ryparker

Summary

The universal search (Cmd+K) currently supports only 3 entity types: legislation, elected officials, and geographies. Users can't search for nominations, committees, or navigate directly to pages like Lobbying or Subpoenas. There's minimal analytics (only query text tracked), and the UX blocks on the slowest query before showing any results.

This issue covers a comprehensive overhaul to make universal search the primary way users navigate Congress.wiki.

Goals

  • New searchable entities: Nominations and committees
  • Page navigation: Instantly find pages like Lobbying, Subpoenas, Schedule, US Code, etc.
  • Streaming results: Each section renders independently as its query completes
  • Fuzzy search: Misspellings still return correct results (already using pg_trgm, extend to new entities)
  • Comprehensive analytics: Track what users search, what they click, and no-result queries
  • Full UX redesign: Both the dialog and full-page search variants

Current State

Entity Searchable Browseable
Legislation Yes Yes
Elected Officials Yes Yes
Geographies Yes Yes
Nominations No Yes
Committees No Yes
Pages (Lobbying, Subpoenas, etc.) No Via nav only

Implementation Phases

Phase 1: Database & GraphQL — Nominations + Committees Search

  • Create search_nominations() PostgreSQL function (fuzzy match on title, citation, nominee names, positions, organizations)
  • Create search_committees() PostgreSQL function (fuzzy match on name, jurisdiction)
  • Track both in Hasura metadata
  • Add lightweight GraphQL fragments for search result cards
  • Split universal search query into independent per-entity queries

Phase 2: Page Navigation Search (Client-Side)

  • Create a client-side page search utility that fuzzy-matches against all navigational pages from navConfig
  • Include keyword aliases (e.g., "bills" → Legislation, "senators" → Officials, "voting" → Roll Calls)
  • Feature-flag-aware filtering
  • Instant results with no DB call

Phase 3: Streaming Architecture

  • Replace Promise.all with individual <Suspense> boundaries per search category
  • Each section makes its own GraphQL call and streams in independently
  • Faster sections (geography, officials) render immediately; slower ones (legislation, nominations) stream in
  • Skeleton loading states per section

Phase 4: Search Result Cards

  • Nomination card: status badge + title + nominee preview + type icon
  • Committee card: name + chamber badge + member count
  • Page card: icon + label + description
  • Consistent hover states, focus rings, keyboard selection

Phase 5: SearchLayout + SearchResults Update

  • Pages render instantly at the top (client-side)
  • Streamed sections below via Suspense children
  • Result ordering: Pages → Geographies → Officials → Committees → Nominations → Legislation

Phase 6: Analytics

New Vercel Analytics events:

  • search_result_click — tracks result type, ID, position, and query
  • search_no_results — tracks queries with zero results
  • Existing search_query event continues as-is

Phase 7: Full UX Redesign

Dialog:

  • Section headers with result count badges
  • Progressive streaming reveal with skeleton → content transitions
  • Keyboard navigation hints
  • Better empty state with suggested searches

Full-page:

  • More results per section (6 instead of 3)
  • Two-column layout on wide screens
  • Filter chips for entity type filtering
  • "View all" links

Affected Repos

  • stockbridge — Frontend search components, GraphQL queries, analytics
  • graphql — PostgreSQL search functions, Hasura metadata

Acceptance Criteria

  • Searching for a nominee name returns nomination results
  • Searching for a committee name returns committee results
  • Searching for "lobbying" shows the Lobbying page as an instant result
  • Misspelled queries (e.g., "commtees") still return fuzzy-matched results
  • Results stream in progressively (faster sections appear first)
  • Click-through analytics fire for all result types
  • No-result queries are tracked
  • Existing search (officials, legislation, geographies) continues working
  • Dialog and full-page variants both reflect the redesign
  • No API endpoints or data leaked to client (server-only data fetching)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions