Documentation Index
Fetch the complete documentation index at: https://mintlify.com/adelpro/quran-search-engine/llms.txt
Use this file to discover all available pages before exploring further.
The search() function accepts any dataset shape as long as each record satisfies the VerseInput type. This allows you to use custom Quran datasets with additional fields like translations, tafsir, or metadata.
From src/types/index.ts:16-20:
export type VerseInput = {
gid: number;
uthmani: string;
standard: string;
};
Minimum requirements
gid: number - Unique verse ID (used to join with morphologyMap)
standard: string - Used for exact text matching
uthmani: string - Used for fuzzy fallback and commonly used for highlighting in UI
If you don’t have separate Uthmani text, set uthmani to the same value as standard.
Basic custom dataset
Here’s a minimal example with custom fields:
import { search, type VerseInput, type WordMap, type MorphologyAya } from 'quran-search-engine';
type MyVerse = VerseInput & {
sura: number;
aya: number;
translation_en?: string;
};
const myQuranData: MyVerse[] = [
{
gid: 1,
standard: 'بسم الله الرحمن الرحيم',
uthmani: 'بِسْمِ ٱللَّهِ ٱلرَّحْمَٰنِ ٱلرَّحِيمِ',
sura: 1,
aya: 1,
translation_en: 'In the name of Allah, the Entirely Merciful, the Especially Merciful.',
},
];
const morphologyMap = new Map<number, MorphologyAya>();
const wordMap: WordMap = {};
const response = search('الله الرحمن', myQuranData, morphologyMap, wordMap, {
lemma: false,
root: false,
});
// Example output:
// response.results[0] => {
// gid: 1,
// sura: 1,
// aya: 1,
// matchType: 'exact',
// matchScore: 6,
// ...
// }
When using custom datasets without morphology data, set lemma: false and root: false in search options. The search will use exact text matching only.
Full example from README
From the README (lines 302-332):
import { search, type VerseInput, type WordMap, type MorphologyAya } from 'quran-search-engine';
type MyVerse = VerseInput & {
sura: number;
aya: number;
translation_en?: string;
};
const myQuranData: MyVerse[] = [
{
gid: 1,
standard: 'بسم الله الرحمن الرحيم',
uthmani: 'بِسْمِ ٱللَّهِ ٱلرَّحْمَٰنِ ٱلرَّحِيمِ',
sura: 1,
aya: 1,
translation_en: 'In the name of Allah, the Entirely Merciful, the Especially Merciful.',
},
];
const morphologyMap = new Map<number, MorphologyAya>();
const wordMap: WordMap = {};
const response = search('الله الرحمن', myQuranData, morphologyMap, wordMap, {
lemma: false,
root: false,
});
// Example output:
// response.results[0] => { gid: 1, sura: 1, aya: 1, matchType: 'exact', matchScore: 6, ... }
With morphology data
For lemma/root matching, provide both morphology map and word map:
MorphologyAya structure
From src/types/index.ts:22-26:
export type MorphologyAya = {
gid: number;
lemmas: string[];
roots: string[];
};
WordMap structure
From src/types/index.ts:28-33:
export type WordMap = {
[key: string]: {
lemma?: string;
root?: string;
};
};
Complete example
import { search, type VerseInput, type MorphologyAya, type WordMap } from 'quran-search-engine';
type CustomVerse = VerseInput & {
sura: number;
aya: number;
page: number;
translation?: string;
};
const customData: CustomVerse[] = [
{
gid: 1,
standard: 'بسم الله الرحمن الرحيم',
uthmani: 'بِسْمِ ٱللَّهِ ٱلرَّحْمَٰنِ ٱلرَّحِيمِ',
sura: 1,
aya: 1,
page: 1,
translation: 'In the name of God, the Most Gracious, the Most Merciful',
},
// ... more verses
];
// Build morphology map
const morphologyMap = new Map<number, MorphologyAya>([
[
1,
{
gid: 1,
lemmas: ['بسم', 'الله', 'الرحمن', 'الرحيم'],
roots: ['ب س م', 'ا ل ه', 'ر ح م', 'ر ح م'],
},
],
// ... more morphology entries
]);
// Build word map
const wordMap: WordMap = {
'الله': { lemma: 'الله', root: 'ا ل ه' },
'الرحمن': { lemma: 'الرحمن', root: 'ر ح م' },
'الرحيم': { lemma: 'الرحيم', root: 'ر ح م' },
// ... more word mappings
};
const response = search('الله', customData, morphologyMap, wordMap, {
lemma: true,
root: true,
});
// Access custom fields in results
response.results.forEach((verse) => {
console.log(`Sura ${verse.sura}, Aya ${verse.aya}, Page ${verse.page}`);
console.log(`Match: ${verse.matchType}, Score: ${verse.matchScore}`);
if (verse.translation) {
console.log(`Translation: ${verse.translation}`);
}
});
TypeScript support
The search() function is generic and preserves your custom type:
import { search, type SearchResponse, type VerseInput } from 'quran-search-engine';
type MyVerse = VerseInput & {
customField: string;
};
const response: SearchResponse<MyVerse> = search(
query,
myData,
morphologyMap,
wordMap,
options
);
// TypeScript knows about your custom fields
response.results.forEach((verse) => {
console.log(verse.customField); // ✓ Type-safe access
});
From src/core/search.ts:303-310:
export const search = <TVerse extends VerseInput>(
query: string,
quranData: TVerse[],
morphologyMap: Map<number, MorphologyAya>,
wordMap: WordMap,
options: AdvancedSearchOptions = { lemma: true, root: true },
pagination: PaginationOptions = { page: 1, limit: 20 },
): SearchResponse<TVerse> => {
Multiple translations
You can include multiple translations in your custom dataset:
type MultilingualVerse = VerseInput & {
sura: number;
aya: number;
translations: {
en: string;
fr?: string;
ur?: string;
id?: string;
};
};
const data: MultilingualVerse[] = [
{
gid: 1,
standard: 'بسم الله الرحمن الرحيم',
uthmani: 'بِسْمِ ٱللَّهِ ٱلرَّحْمَٰنِ ٱلرَّحِيمِ',
sura: 1,
aya: 1,
translations: {
en: 'In the name of Allah, the Entirely Merciful, the Especially Merciful.',
fr: 'Au nom d\'Allah, le Tout Miséricordieux, le Très Miséricordieux.',
ur: 'اللہ کے نام سے جو بڑا مہربان نہایت رحم والا ہے',
},
},
];
GID mapping
Ensure that your gid values match the gid keys in your morphologyMap. The search engine uses gid to join verse data with morphology data.
The gid (global ID) must be:
- Unique for each verse
- Consistent between your verse data and morphology data
- A positive integer
// ✓ Correct: GIDs match
const data = [{ gid: 1, ... }];
const morphMap = new Map([[1, { gid: 1, lemmas: [...], roots: [...] }]]);
// ✗ Incorrect: GID mismatch
const data = [{ gid: 1, ... }];
const morphMap = new Map([[2, { gid: 2, lemmas: [...], roots: [...] }]]);
Empty morphology
If you don’t have morphology data, you can use empty collections:
const morphologyMap = new Map<number, MorphologyAya>();
const wordMap: WordMap = {};
const response = search(
query,
myData,
morphologyMap,
wordMap,
{
lemma: false, // Disable lemma matching
root: false, // Disable root matching
}
);
Without morphology data, the search will only perform exact text matching and fuzzy fallback (if enabled).
You can include any additional metadata in your custom type:
type EnhancedVerse = VerseInput & {
sura: number;
aya: number;
page: number;
juz: number;
hizb: number;
manzil: number;
ruku: number;
sajda?: boolean;
revelation_order: number;
revelation_place: 'mecca' | 'medina';
audio_url?: string;
tafsir?: {
author: string;
text: string;
}[];
};
All fields are preserved in search results and fully typed when using TypeScript.