Skip to main content
Our new developer certification is live!

Search

Page component for search and filtering functionality with faceted search, pagination, and responsive filter sidebar.

Props

PropTypeRequiredDefaultDescription
resultsFilteredContentItem[]Yes-Filtered and paginated search results
facetsFilterFacetsYes-Facet counts for content types, subjects, technology, and authors
totalResultsnumberYes-Total number of results (before pagination)
currentPagenumberYes-Current page number (1-indexed)

Usage

import Search from '@/components/pages/Search';

<Search
  results={paginatedResults}
  facets={facetData}
  totalResults={45}
  currentPage={1}
/>

Features

  • Faceted search: Filter by content type (Blogs, Guides, Live Streams), subjects, and technology
  • Text search: Typeahead-based search across selected content types
  • Pagination: Navigate through results (20 per page)
  • Responsive design:
    • Mobile: Collapsible filter sidebar with toggle button
    • Desktop: Fixed sidebar with filters always visible
  • URL state management: Filters and pagination reflected in URL parameters
  • Contextual facets: Facet counts update based on selected filters
  • Empty states: Helpful messages when no results found

Filter Behavior

  • Text search: Uses Contentstack typeahead tokens with AND matching across tokens (up to 5 tokens). Matches entries directly, matches content by author/host/guest when a person token matches, and also matches taxonomy term UIDs when tokens align with taxonomies.
  • Content Types: Can select multiple (Blogs, Guides, Live Streams)
  • Subjects: Can select multiple subject taxonomy terms
  • Technology: Can select multiple technology taxonomy terms (e.g. React, Next.js)
  • Disabled filters: Options with 0 count are greyed out but still visible
  • URL parameters: ?q=graphql&types=blogpost,guide&subjects=ai&technology=react&page=2

Performance Notes

  • Search results and facets are built from a shared cached dataset to reduce Contentstack requests.
  • Search queries fetch a minimal field set (titles, URLs, taxonomy terms, metadata, and author refs) instead of full entries.
  • Cache is bypassed in preview mode to keep live preview accurate.
  • Typeahead calls are shared between results and suggestions to avoid duplicate network requests.

Code Structure

  • lib/contentstack/search/dataset.ts: Builds the shared dataset and removes guide chapters.
  • lib/contentstack/search/typeahead.ts: Tokenizes text input and performs Contentstack typeahead queries.
  • lib/contentstack/search/entryUtils.ts: Normalizes taxonomy/person data and builds facet counts.
  • lib/contentstack/search/suggestions.ts: Maps entries to lightweight suggestion cards.
  • lib/contentstack/filters.ts: Orchestrates the pipeline (typeahead → filters → facets → pagination).

Layout Structure

  1. Header Section:

    • Result count title
    • Mobile filter toggle button
  2. Mobile Filters (when toggled):

    • Collapsible SearchSidebar component
  3. Main Content:

    • Desktop sidebar with SearchSidebar
    • Results list using List organism
    • Pagination component (when needed)

URL Parameters

  • q: Text search query (split into tokens for AND matching, up to 5 tokens)
  • types: Comma-separated content types (e.g., blogpost,guide)
  • subjects: Comma-separated subject term_uids (e.g., ai,headless)
  • technology: Comma-separated technology term_uids (e.g., react,next)
  • page: Page number (omitted for page 1)
  • page fallback: Invalid, empty, or non-positive page values default to 1

Filter State Management

  • Filters stored in URL search parameters
  • Changing filters resets to page 1
  • Uses useSearchParams and useRouter for URL updates
  • Preserves filter selections across page navigation

Components Used

  • SearchSidebar - Filter sidebar (molecule)
  • Pagination - Page navigation (molecule)
  • List - Results display (organism)
  • Title - Page title (atom)
  • Button - Filter toggle button (atom)
  • Sidebar - Desktop sidebar container (atom)

Notes

  • Client component (uses hooks for state management)
  • Default state shows all content types
  • Facet counts are contextual (update based on other filters)
  • Pagination only shows when totalPages > 1
  • Mobile filter button only visible on mobile (lg:hidden)