Files
2026-03-07 11:04:18 +11:00

8.1 KiB

Changelog

1.8.1

Added

  • POST support on /api/search — the search endpoint now accepts both GET and POST requests, enabling compatibility with clients that send search queries via POST
  • Compatibility query parameters on /api/search:
    • pageNumber — alias for page (takes precedence when both are provided)
    • numResults — requested result count hint (accepted and ignored; backend controls pagination)
    • format — response format hint (e.g. json)
    • imageProxy — client image-proxy preference flag (informational)
    • safesearch — safe search level (0 off, 1 moderate, 2 strict; accepted for compatibility)

Added

  • Bookmarks — save any web or image result for later reading
    • Bookmark icon on every search result card (web and image)
    • Bookmark toggle in image lightbox viewer
    • Dedicated /bookmarks page with filter tabs (All / Web / Images)
    • Web bookmarks shown as cards with favicons, engine badges, and content snippets
    • Image bookmarks displayed in masonry grid with hover overlays
    • Remove individual bookmarks with trash button
    • Paginated with "Load more" for large collections
    • Bookmarks link in homepage footer and results page footer
    • Stored in SQLite (same database as other app settings)
    • Full CRUD API: GET/POST /api/bookmarks, DELETE /api/bookmarks/{id}, DELETE /api/bookmarks/by-url/{url}, GET /api/bookmarks/urls

1.5.0

Added

  • Redis search cache — identical searches within a configurable time window are served from Redis cache instead of re-querying upstream engines
    • Cache TTL configurable via UI (Settings → Cache tab) from 0 hours (disabled) to 1 week
    • Default TTL: 6 hours
    • TTL setting persisted in SQLite
    • Cache key is deterministic hash of query + category + page + image_size + engines
    • Only successful results (with at least 1 result) are cached
  • Cache management UI — new "Cache" tab in Settings modal
    • Redis connection status indicator (green dot = connected)
    • Preset buttons: Disabled, 1h, 6h, 12h, 24h, 3 days, 1 week
    • Continuous slider for fine-grained TTL control
    • "Clear all cached results" flush button
  • Settings APIGET/PUT /api/settings for cache_ttl_hours, DELETE /api/cache for flushing
  • Redis is optional — when REDIS_URL is not set or Redis is unreachable, caching is silently disabled

1.4.0

Added

  • Accessibility overhaul (P0)
    • Image result cards are now real <a> links — supports open-in-new-tab, Cmd/Ctrl-click, and copy-link
    • aria-label on all icon-only buttons (settings, clear, close, lightbox nav, engine toggles, domain remove, pagination arrows, error dismiss)
    • Search input has proper semantics: <label>, name="q", type="search", role="combobox", aria-autocomplete, aria-expanded, aria-activedescendant
    • Autocomplete list uses role="listbox" and role="option" with aria-selected
    • Visible keyboard focus (focus-visible:ring-2) on all interactive elements; removed bare outline-none
  • Page structure (P1)
    • "Skip to main content" link for keyboard users
    • Proper heading hierarchy (h1 on home, h2 for results/no-results, sr-only screen-reader headings)
    • <nav> landmarks for category tabs and pagination, <aside> for stats sidebar
  • Live announcements (P1)
    • aria-live="polite" region announces loading state and result counts to screen readers
    • aria-live="assertive" on error toast for immediate announcement
    • Loading spinner has role="status" with sr-only text
  • Custom favicon — search magnifying glass SVG replaces default Vite favicon (eliminates 404 console errors)
  • Agent-friendly API response (P2)
    • Every result now includes result_id (stable unique ID), rank (position in result list), and engine
    • SearchResponse includes timestamp (ISO 8601), total_results, and has_next for cursor-based pagination
    • EngineError includes code, details, and retry_hint fields
    • New APIError standard error model (code/message/details/retry_hint) used on all error responses
    • Standardized 404 errors on engine and domain endpoints with consistent JSON schema
  • API documentation (P2)
    • All API endpoints include copy-paste curl examples and sample JSON responses in OpenAPI descriptions
    • API version bumped to 1.4.0 with descriptive title
  • Rate-limit headers (P2)
    • X-Response-Time-Ms and X-RateLimit-Limit/X-RateLimit-Remaining headers on all responses
    • Global exception handler returns standardized APIError JSON for unhandled errors
  • URL state (P2)
    • engines parameter supported in URL for reproducible sessions (?q=hello&engines=google,bing)
  • Settings modal, lightbox, and category tabs all have role="dialog", aria-modal, aria-expanded, aria-pressed, and aria-current where appropriate

1.3.0

Added

  • Pinterest-style masonry image layout — images display at their natural aspect ratios using CSS columns, creating a dynamic waterfall grid instead of fixed-size squares
  • Image size filter — filter image results by size (All, Large, Medium, Small); passed to search engines server-side (Google tbs=isz, Bing qft=filterui:imagesize, DuckDuckGo size param)
  • Image size filter state is synced in the URL (&image_size=large)
  • Lightbox navigation — left/right arrow buttons and keyboard arrow keys to browse images; Escape to close; position counter (e.g. "3 / 70")
  • Visited link styling — clicked web result links turn purple to distinguish from unvisited links

Fixed

  • Settings modal now properly constrained to viewport on mobile (max-h-[90vh]) with scrollable content area and pinned footer
  • Search stats section defaults to collapsed on mobile to save screen space

1.2.0

Changed

  • Google engine rewrite — replaced Startpage proxy with direct Google scraping using SearXNG's async progressive response approach (asearch=arc). Parses MjjYud containers, extracts URLs from redirect wrappers, and handles base64 thumbnails for image search.
  • Bing engine rewrite — added direct Bing scraping with SearXNG-style cookie handling, base64 redirect URL decoding, and CAPTCHA detection. Automatically falls back to Yahoo (Bing-powered) when Bing blocks the request.

1.1.0

Added

  • Pagination — page navigation for web and image results with URL-synced state (?q=...&page=2)
  • Search stats sidebar — per-engine result counts and status indicators (green/amber/red), collapsible on mobile, sticky sidebar on desktop
  • Domain exclusion — exclude specific websites from search results
    • SQLite-backed persistence (backend/data/hey_search.db)
    • REST API: GET/POST /api/excluded-domains, DELETE /api/excluded-domains/{domain}
    • Sub-domain matching (excluding example.com also excludes sub.example.com)

Changed

  • Unified settings modal — replaced separate Engines and Excluded Sites buttons with a single Settings button that opens a tabbed modal
  • Added footer on both home and results pages with a link to the interactive API documentation (Swagger UI at /docs)
  • URL now reflects search state (query, category, page) and supports browser back/forward

1.0.0 — 2026-02-23

Added

  • Initial release of HeySearch metasearch engine
  • Backend (Python / FastAPI)
    • Async search orchestrator querying Brave, DuckDuckGo, Google, and Bing concurrently
    • Retry mechanism with exponential backoff for upstream engine failures
    • Autocomplete endpoint cascading through Google → DuckDuckGo → Brave
    • Engine management API (list, enable/disable)
    • OpenAPI spec served via Swagger UI (/docs) and Redoc (/redoc)
    • Dependency management with uv
  • Frontend (React + Vite + TypeScript + Tailwind CSS)
    • Mobile-first responsive search UI with shadcn theming
    • Web results page with favicons, engine badges, and content snippets
    • Image results grid with lightbox viewer
    • Live autocomplete with keyboard navigation
    • Engine settings modal with toggle switches
    • Toast notifications for upstream engine errors
  • Docker — multi-stage Dockerfile (Node frontend build → Python runtime)