1.0.4 • Published 5 months ago

sanity-search v1.0.4

Weekly downloads
-
License
MIT
Repository
-
Last release
5 months ago

Sanity Search Component

A lightweight and configurable search component for Sanity.io and Next.js websites, built with React and TypeScript.

✨ Features

  • 🔍 Instant Search with Debouncing
  • 🔥 Highlight Matched Keywords
  • 🎨 Customizable UI & Icons
  • Pluggable Search Query Generator

💻 Demo

Live Demo

🚀 Installation

npm install sanity-search
# or
yarn add sanity-search

🛠 Usage

Basic Implementation

First, create a server action that returns a list of search results.

// actions/search.ts
"use server";
import { createSanitySearchQuery } from "sanity-search";

const MINIMUM_SEARCH_LENGTH = 2;

export default async function search(searchTerm: string) {
  if (!searchTerm || searchTerm.length < MINIMUM_SEARCH_LENGTH) {
    return [];
  }

  try {
    const { query, params } = createSanitySearchQuery({
      documentFragment: `{
        title,
        description,
        body,
        "href": slug.current
      }`,
      documentType: "blog.post",
      searchTerm,
      searchableFields: ["title", "description", "body"],
    });

    const data = await loadQuery<any[]>({
      params,
      query,
    });

    if (!data) {
      return [];
    }

    return data;
  } catch (error) {
    console.error("Error searching blog posts:", error);
    return [];
  }
}

Then, use the SanitySearch component in your search component, passing in the search server action.

// components/search.tsx
"use client";

import Link from "next/link";
import { SanitySearch } from "sanity-search";

import search from "../actions/search";

export default function Search() {
  return (
    <SanitySearch 
      config={{
        behavior: {
          searchDebounceDelay: 500,
          minimumSearchLength: 2,
        },
        ui: {
          placeholder: "Search",
          noResultsText: "No results found. Please try a different search.",
          searchIcon: "🔍",
          loadingIcon: "⏳",
        },
      }} 
      onSearch={search}
      LinkComponent={Link}
    />
  );
}

📌 Props

<SanitySearch />

PropTypeRequiredDescription
configSanitySearchConfigSearch behavior & UI config
onSearch(searchTerm: string) => Promise<SearchResult[]>Function to fetch search results
classNamestringCustom class for styling
LinkComponent`React.ComponentType | ❌ | Custom link component

SanitySearchConfig

PropertyTypeDefaultDescription
behavior.searchDebounceDelaynumber500Delay before search triggers
behavior.minimumSearchLengthnumber2Min. characters to start searching
ui.placeholderstring"Search"Input placeholder text
ui.noResultsTextstring"No results found. Please try a different search."Text when no results
ui.searchIconReact.ReactNodenullCustom search icon
ui.loadingIconReact.ReactNodenullCustom loading icon
ui.isHighlightEnabledbooleantrueHighlight search matches

🔗 API Helpers

createSanitySearchQuery

Generates a structured GROQ query to fetch data from Sanity.io and returns the query and params.

const {query, params} = createSanitySearchQuery({
  documentType: "post",
  documentFragment: "{ title, description, body, href }",
  searchableFields: ["title", "description", "body"],
  searchTerm: "example",
});

🎨 Styling

You can customize the component using classes, here is a list of classes you can use:

  • sanity_search
  • sanity_search__input_container
  • sanity_search__input
  • sanity_search__icon_container
  • sanity_search__dropdown
  • sanity_search__result_item
  • sanity_search__result_title
  • sanity_search__result_description
  • sanity_search__no_results

📜 License

MIT License © 2025 Imad Attif

🌟 Contributions

PRs and feedback are welcome! 🚀

1.0.4

5 months ago

1.0.3

5 months ago

1.0.2

5 months ago

1.0.1

5 months ago

1.0.0

5 months ago