A modern search bar application built with Qwik and Typesense, featuring instant search capabilities.
- ⚡ Instant Search - Real-time search powered by InstantSearch.js
- 🎨 Modern UI - Clean, responsive design with gradient animations
- 📚 Book Display - Grid layout with book covers, ratings, and metadata
- 🔍 Smart Search - Weighted field search with typo tolerance
- 📱 Responsive - Adapts to mobile, tablet, and desktop screens
- ⭐ Rating Display - Visual star ratings and review counts
- 🔄 Loading Indicators - Built-in loading states from InstantSearch.js
- Qwik - Resumable framework for building fast web applications
- Qwik City - Directory-based routing and layouts
- Typesense - Open-source search engine
- InstantSearch.js - UI library for building search experiences
- typesense-instantsearch-adapter - Adapter to connect Typesense with InstantSearch.js
- Tailwind CSS - Utility-first CSS framework
- Vite - Next-generation build tool
- Node.js 18+ and npm 9+
- Docker (for running Typesense locally). Alternatively, you can use a Typesense Cloud cluster.
cd typesense-qwik-js-searchnpm installCreate a .env file in the project root:
PUBLIC_TYPESENSE_API_KEY=xyz
PUBLIC_TYPESENSE_HOST=localhost
PUBLIC_TYPESENSE_PORT=8108
PUBLIC_TYPESENSE_PROTOCOL=http
PUBLIC_TYPESENSE_INDEX=books├── src/
│ ├── components/
│ │ ├── BookCard.tsx # Individual book card component
│ │ ├── BookList.tsx # Book list grid component
│ │ ├── Heading.tsx # Page heading with branding
│ │ └── icons.tsx # SVG icons (GitHub, Qwik)
│ ├── routes/
│ │ └── index.tsx # Main page with InstantSearch integration
│ ├── types/
│ │ └── Book.ts # TypeScript type definitions
│ ├── utils/
│ │ └── typesense.ts # Typesense-InstantSearch adapter config
│ └── global.css # Global styles and InstantSearch CSS
└── public/
Run a local Typesense instance using Docker:
docker run -p 8108:8108 \
--volume /tmp/typesense-data:/data \
typesense/typesense:0.25.2 \
--data-dir /data \
--api-key=xyz \
--enable-corsIf you have the Gin backend running, trigger a sync:
curl -X POST http://localhost:3000/syncOr manually create a collection and index documents using the Typesense API.
npm run devOpen http://localhost:5173 to see the search bar in action.
The Typesense-InstantSearch adapter is configured in src/utils/typesense.ts:
import TypesenseInstantSearchAdapter from "typesense-instantsearch-adapter";
export const typesenseInstantsearchAdapter = new TypesenseInstantSearchAdapter({
server: {
apiKey: import.meta.env.PUBLIC_TYPESENSE_API_KEY || "xyz",
nodes: [
{
host: import.meta.env.PUBLIC_TYPESENSE_HOST || "localhost",
port: Number(import.meta.env.PUBLIC_TYPESENSE_PORT) || 8108,
protocol: import.meta.env.PUBLIC_TYPESENSE_PROTOCOL || "http",
},
],
},
additionalSearchParameters: {
query_by: "title,authors",
query_by_weights: "4,2", // Title weighted 2x more than authors
num_typos: 1, // Allow 1 typo for fuzzy matching
sort_by: "ratings_count:desc", // Sort by popularity
},
});
export const searchClient = typesenseInstantsearchAdapter.searchClient;
export const INDEX_NAME = import.meta.env.PUBLIC_TYPESENSE_INDEX || "books";The search UI is powered by InstantSearch.js widgets initialized in useVisibleTask$:
- searchBox: Provides the search input with built-in reset and loading indicators
- hits: Handles search results and transforms them into the Book type
- configure: Sets search parameters like hits per page
The integration uses transformItems to update Qwik signals with search results, allowing reactive UI updates while leveraging InstantSearch's powerful features.
This implementation follows the pattern from the official Typesense Qwik showcase:
- Adapter Setup: The
typesense-instantsearch-adapterbridges Typesense and InstantSearch.js - Client-Side Initialization: InstantSearch widgets are initialized in
useVisibleTask$(runs after component renders) - Widget Integration: InstantSearch widgets (searchBox, hits) are mounted to DOM containers
- Reactive Updates: The
transformItemscallback updates Qwik signals with search results - Custom Rendering: Results are rendered using custom Qwik components (BookCard, BookList)
For production deployment:
-
Set the environment variables to point to your Typesense Cloud cluster:
PUBLIC_TYPESENSE_API_KEY=your-production-api-key PUBLIC_TYPESENSE_HOST=xxx.typesense.net PUBLIC_TYPESENSE_PORT=443 PUBLIC_TYPESENSE_PROTOCOL=https PUBLIC_TYPESENSE_INDEX=books
-
Build the application:
npm run build
-
Preview the production build:
npm run preview
MIT