Feature: Search Functionality
Relevant source files
The following files were used as context for generating this wiki page:The search functionality is a core feature of the CertDb platform, providing users with a fast and efficient way to find cybersecurity certifications. It is implemented as a client-side fuzzy search, allowing users to search by certification title, acronym, provider, aliases, and associated career paths. This approach ensures a responsive user experience without requiring server-side processing for each query.
The search is powered by the fuse.js library, which is configured to perform weighted searches across multiple fields, delivering relevant results even with partial or misspelled queries. The system is optimized for performance by fetching a pre-computed search index alongside the certification data.
Sources: README.md:16-18, src/components/astro/database/reactive-datatable.tsx:48-51, 162-168
Architecture
The search architecture is entirely client-side. When a user visits a page with a searchable data table (like the main certification database), the browser fetches the complete dataset and a pre-generated Fuse.js index. All subsequent search operations are performed locally in the user's browser, providing instant feedback.
This diagram illustrates the client-side search architecture.
Core Technology
The search functionality is built using Fuse.js, a powerful, lightweight fuzzy-search library. The dependency is declared in the project's package.json.
{
"dependencies": {
"fuse.js": "^7.1.0"
}
}
Sources: package.json:20
Fuse.js is initialized within the ReactiveDatatable component, using a pre-computed index for optimal performance.
Sources: src/components/astro/database/reactive-datatable.tsx:48-51, 217-224
Search Configuration
The behavior of the fuzzy search is defined in a central configuration file. This configuration specifies which fields of the certification data to search and assigns a weight to each, influencing the relevance scoring of the search results.
Sources: src/pages/database/fuse.config.ts
Fuse.js Options
The FuseConfig object defines the search parameters. The keys array is particularly important as it dictates which data fields are searchable and their relative importance.
| Property | Value | Description |
|---|---|---|
keys | Array of Objects | An array of objects specifying the fields to search in and their weights. |
isCaseSensitive | false | The search is case-insensitive. |
useExtendedSearch | true | Enables advanced search features. |
Sources: src/pages/database/fuse.config.ts:4-26
Searchable Fields & Weights
Higher weight values mean that matches in that field will be considered more relevant.
| Field Name | Weight |
|---|---|
title | 0.7 |
acronym | 0.6 |
aliases | 0.5 |
provider | 0.4 |
career_paths | 0.3 |
Sources: src/pages/database/fuse.config.ts:5-23
Here is the full configuration object:
// src/pages/database/fuse.config.ts
import type { IFuseOptions } from "fuse.js";
import type { CertificationMetadata } from "../../types/certification-metadata.ts";
export const FuseConfig: IFuseOptions<CertificationMetadata> = {
keys: [
{
name: "title",
weight: 0.7,
},
{
name: "acronym",
weight: 0.6,
},
{
name: "aliases",
weight: 0.5,
},
{
name: "provider",
weight: 0.4,
},
{
name: "career_paths",
weight: 0.3,
},
],
isCaseSensitive: false,
useExtendedSearch: true,
};
Sources: src/pages/database/fuse.config.ts:4-26
Data Flow and Implementation
The search functionality is orchestrated by the ReactiveDatatable component, which manages state, data fetching, and rendering of results.
Initial Data Loading
On component mount, a useEffect hook fetches both the certification data (data.json) and the pre-computed Fuse.js index (data-index.json). This index is generated during the site's build process. Using a pre-computed index significantly speeds up the initialization of Fuse.js on the client.
This sequence diagram shows the data loading process.
The API endpoint at src/pages/database/data-index.json.ts is responsible for creating and serving this index.
// src/pages/database/data-index.json.ts
export const GET: APIRoute = async () => {
const index = Fuse.createIndex(
FuseConfig.keys!,
await getCertificationMetadata(),
);
return Response.json(index.toJSON());
};
Sources: src/pages/database/data-index.json.ts:8-14
This pattern is also used for career-path-specific pages, demonstrating its reusability.
Sources: src/pages/career-paths/[path]/data-index.json.ts:14-20
User Interaction and Filtering
The search is triggered by user input into the HeaderSearchBar component.
- The
HeaderSearchBarcomponent renders an<input type="text" name="query">. - As the user types, the
onInputevent handler updates thequerystate within theReactiveDatatablecomponent. - A
useMemohook inReactiveDatatableis dependent on thequerystate. Whenquerychanges, this hook re-executes. - If the
queryis not empty, it callsall_data.search(query)on the Fuse.js instance. - The results from the search are stored in
display_data, which is then used to render the filtered list of certifications in the table.
This flow is illustrated below.
The core filtering logic is encapsulated in this useMemo hook:
// src/components/astro/database/reactive-datatable.tsx
const display_data = useMemo(
() => {
if (query) {
const filtered_data = all_data.search(query).flatMap((result) => result.item);
set_pagination((prev) => ({
...prev,
total_pages: Math.ceil(filtered_data.length / pagination.per_page),
}));
return filtered_data;
}
return all_raw_data;
},
[
all_data,
query,
all_raw_data,
pagination.per_page,
],
);
Sources: src/components/astro/database/reactive-datatable.tsx:162-178
UI Components
HeaderSearchBar
A simple, reusable React component that provides the user interface for entering search queries. It's a controlled component whose value is managed by its parent (ReactiveDatatable).
Sources: src/components/astro/common/header-search-bar.tsx
ReactiveDatatable
This is the central component that integrates the search bar, data fetching, state management, and results display. It maintains the state for the search query, the full dataset, the Fuse.js instance, and pagination.
Sources: src/components/astro/database/reactive-datatable.tsx
Conclusion
The search functionality in CertDb is a well-architected, client-side feature that prioritizes user experience and performance. By leveraging Fuse.js with a pre-computed index, it provides fast, relevant, and fault-tolerant search results across the certification database. The modular design, with a clear separation of concerns between configuration, UI components, and state management, makes the system robust and maintainable.