Skip to Content

🔍 Search Page

This guide explains how to implement a full search flow using the Zezo OTT API and UI Kit, powered by React Query and Next.js App Router.


📁 Folder Structure

app/ ├── search/ │ └── page.tsx # Server Component to fetch search results ├── _components/ │ └── SearchClient.tsx # Client Component for <ZezoSearch />

📄 File: app/search/page.tsx

This is a Server Component that:

  • Extracts the search query from the searchParams object.
  • Calls the Zezo API Client to fetch search results.
  • Passes both initialQuery and initialData to the <SearchClient /> Client Component.

✅ Usage Purpose

This file ensures that search data is fetched server-side before rendering the page. This improves SEO and performance for the search experience.


💡 Implementation

import { zezoClient } from "@/lib/zezoClient"; import SearchClient from "../_components/SearchClient"; import { IContentData } from "@zezosoft/zezo-ott-api-client"; export default async function SearchPage({ searchParams, }: { searchParams: { q?: string }; }) { const query = searchParams.q?.trim() || ""; let data: IContentData[] = []; if (query.length > 0) { try { const results = await zezoClient().contents.fetchSearchResults(query); data = results.data.data || []; } catch { data = []; } } return <SearchClient initialQuery={query} initialData={data} />; }

📄 app/_components/SearchClient.tsx

This is a Client Component responsible for:

  • Managing client-side search input
  • Navigating on input change
  • Displaying results using <ZezoSearch /> from the UI Kit

🔌 Props

PropTypeRequiredDescription
initialQuerystring✅ YesThe query string fetched from the URL
initialDataIContentData[]✅ YesThe data fetched from the server for hydration

🧠 Logic

  • useState tracks the search input.
  • useTransition enables low-priority routing.
  • router.push updates the query parameter on typing.
  • Results are shown only if the query is not empty.

🚀 Code Example

"use client"; import React, { useEffect, useState, useTransition } from "react"; import { useRouter } from "next/navigation"; import { Search as ZezoSearch } from "@zezosoft/zezo-ott-react-ui-kit"; import { IContentData } from "@zezosoft/zezo-ott-api-client"; interface Props { initialData: IContentData[]; initialQuery: string; } export default function SearchClient({ initialQuery, initialData }: Props) { const router = useRouter(); const [inputValue, setInputValue] = useState(initialQuery); const [isPending, startTransition] = useTransition(); useEffect(() => { setInputValue(initialQuery); }, [initialQuery]); return ( <ZezoSearch value={inputValue} onChange={(value) => { setInputValue(value); startTransition(() => { router.push(`/search?q=${encodeURIComponent(value)}`, { scroll: false, }); }); }} isLoading={isPending} results={inputValue.trim().length > 0 ? initialData : []} /> ); }

📦 Props for SearchClient

PropTypeDescription
initialQuerystringThe search term from the URL query string
initialDataIContentData[]The search result data from server-side prefetching

🧠 How It Works

  • URL query (q) is extracted on the server.
  • Search data is prefetched using zezoClient().
  • Data is passed to the client via props.
  • <SearchClient /> renders the <ZezoSearch /> component.
  • Client-side navigation triggers updates on input change.

✅ This setup combines server-side data fetching with client-side hydration for optimal performance and user experience.

🖼️ UI Preview

Here’s how the Search component looks in action:

Search UI


📝 Notes

  • Search results must follow the IContentData[] format.
  • Ensure QueryClientProvider is configured at the app root (e.g., app/layout.tsx).
  • <ZezoSearch /> is fully customizable — including theme, layout, empty state, and more.
  • No new search is triggered when the query string is empty (empty q param).
  • This implementation does not require react-hot-toast, keeping dependencies minimal.

💡 Tip: You can extend this setup with:

  • Filter chips (genre, language, etc.)
  • Pagination or infinite scroll
  • Category toggles or tabs for richer discovery
Last updated on