> ## Documentation Index
> Fetch the complete documentation index at: https://developer.voyado.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Search

export const SearchPage = () => {
  const [query, setQuery] = useState("");
  const [results, setResults] = useState([]);
  useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const q = params.get("q");
    if (q) {
      setQuery(q);
      runSearchWithQuery(q);
    }
  }, []);
  async function runSearchWithQuery(q) {
    try {
      const res = await fetch("https://api.mintlify.com/discovery/v1/search/developer.voyado.com", {
        method: "POST",
        headers: {
          Authorization: "Bearer mint_dsc_Uc2wE24ctv3G2KQniLXQMA",
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          query: q,
          pageSize: 10
        })
      });
      console.log("STATUS:", res.status);
      const data = await res.json();
      console.log("DATA:", data);
      setResults(Array.isArray(data) ? data : data.results || []);
    } catch (err) {
      console.error("SEARCH ERROR:", err);
    }
  }
  function runSearch() {
    runSearchWithQuery(query);
  }
  function cleanContent(text) {
    if (!text) return "";
    return text.replace(/<[^>]+>/g, "").replace(/^#{1,6}\s+/gm, "").replace(/\*\*(.+?)\*\*/g, "$1").replace(/\*(.+?)\*/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/^\s*[-*>]\s+/gm, "").replace(/\n+/g, " ").trim();
  }
  function highlightQuery(text, q) {
    if (!q || !text) return text;
    const escaped = q.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
    const parts = text.split(new RegExp(`(${escaped})`, "gi"));
    return parts.map((part, i) => part.toLowerCase() === q.toLowerCase() ? <span key={i} style={{
      color: "#fe4949c5",
      fontWeight: 600
    }}>{part}</span> : part);
  }
  return <div className="space-y-4">
    <style>{`
      .search-submit-btn {
        background-color: rgba(254, 74, 73, 0.3) !important;
      }
      .search-input {
        border-color: #6b7280 !important;
      }
      .search-preview strong {
        font-weight: 700 !important;
      }
    `}</style>

    <form onSubmit={e => {
    e.preventDefault();
    runSearch();
  }} className="flex gap-2">

      <input value={query} onChange={e => setQuery(e.target.value)} placeholder="Search docs..." className="border rounded px-3 py-2 w-full search-input" />

      <button type="submit" className="border rounded px-4 py-2 search-submit-btn">
        Search
      </button>
    </form>

<div className="mt-10 space-y-5">
  {results.map((result, i) => {
    const title = result.metadata?.title || result.path;
    const cleanPath = `/${result.path}`;
    const cleaned = cleanContent(result.content);
    const preview = cleaned.length > 180 ? cleaned.slice(0, 180) + "..." : cleaned;
    return <a key={i} href={cleanPath} target="_blank" rel="noopener noreferrer" onClick={e => {
      e.preventDefault();
      window.open(cleanPath, "_blank", "noopener,noreferrer");
    }} className="block border-b pb-5 no-underline">
            <div className="text-lg font-semibold text-primary">
              {title}
            </div>

            <p className="mt-3 text-sm leading-6 text-gray-500 search-preview">
              {highlightQuery(preview, query)}
            </p>

            <div className="mt-1 text-sm text-gray-400">
              {result.path?.replace("/docs/docs/", "/docs/")}
            </div>


          </a>;
  })}

    </div>

    </div>;
};

<SearchPage />
