Fields Property Control which fields are displayed in search results
What are Fields? The fields prop determines which properties from your data are shown in the results list. This is different from keys which controls what you search in .
In this example: let fields = ['japanese', 'english'] Even though the data contains japanese, romaji, and english, only japanese and english will be displayed in the results.
💡 Tip: You can still search through all fields, but you'll only see the
ones specified in fields.
Copy <script lang ="ts" >
import data from '../../data/japanese-data.json' ;
import { Fuzzy } from 'flexilexi' ;
let fields = ['japanese' , 'english' ];
</script >
<Fuzzy {data } {fields } divClass ="p-4" div2Class ="p-4" />
Keys Property Control which fields are searchable in your data
What are Keys? The keys prop determines which properties in your data are searched . When you type in the search box, FuzzySearch only looks through
the fields specified in keys.
In this example: let keys = ['romaji', 'english'] Your search will only match text in the romaji and english fields. Searches won't match text in the japanese field.
🔍 Try it: Type "iku" (romaji) or "go" (english) to find results. Japanese
characters won't work because japanese is not in the keys array.
Copy <script lang ="ts" >
import data from '../../data/japanese-data.json' ;
import { Fuzzy } from 'flexilexi' ;
let keys = ['romaji' , 'english' ];
</script >
<Fuzzy {data } {keys } divClass ="p-4" div2Class ="p-4" />
Threshold Property Set the initial fuzziness level for search matching
What is Threshold? The thresholdValue prop controls how "fuzzy" the search is.
It's a number between 0.0 (exact matches only) and 1.0 (very loose matching).
In this example: thresholdValue=0.6 The search starts with moderate fuzziness (0.6), allowing for typos and partial matches.
Threshold Guide: 0.0 - 0.2: Strict matching, minimal typos allowed 0.3 - 0.5: Moderate fuzziness, some flexibility 0.6 - 0.8: Loose matching, forgiving of mistakes 0.9 - 1.0: Very loose, matches almost anything 🎯 Try it: Use the fuzziness slider to see how different thresholds affect your
results. Lower values give more precise results, higher values cast a wider net.
Copy <script lang ="ts" >
import data from '../../data/japanese-data.json' ;
import { Fuzzy } from 'flexilexi' ;
</script >
<Fuzzy {data } thresholdValue ={0.3} divClass ="p-4" div2Class ="p-4" />
Modular modular, flexible architecture lets you build search experiences exactly the way you want.
Choose your level of customization:
Headless Component Composable Copy <script lang ="ts" >
import data from '../../data/japanese-data.json' ;
import { useFuzzySearch, SearchInput , SearchResults } from '$lib' ;
const search = useFuzzySearch ({ data, thresholdValue : 0.4 });
</script >
<div class ="p-4" >
<SearchInput value ={search.searchQuery} onChange ={search.setSearchQuery} />
<SearchResults results ={search.results} />
</div >
useFuzzySearch Fuzzy Search Example Results (0) Start typing to search...
Copy <script lang ="ts" >
import { useFuzzySearch } from 'flexilexi' ;
import data from '../../data/japanese-data.json' ;
const search = useFuzzySearch ({
data,
keys : ['japanese' , 'romaji' , 'english' ],
thresholdValue : 0.6 ,
debounceMs : 300
});
let searchValue = $state('' );
function handleSearchInput (event: Event ) {
const target = event.target as HTMLInputElement ;
searchValue = target.value ;
search.setSearchQuery (searchValue);
}
function handleThresholdChange (event: Event ) {
const target = event.target as HTMLInputElement ;
search.setThreshold (Number (target.value ));
}
</script >
<div class ="mx-auto max-w-4xl p-6" >
<h1 class ="mb-6 text-3xl font-bold" > Fuzzy Search Example</h1 >
<div class ="mb-6 space-y-4" >
<div >
<label for ="search" class ="mb-2 block text-sm font-medium" >
Search (Japanese, romaji, or English):
</label >
<input
id ="search"
type ="text"
value ={searchValue}
oninput ={handleSearchInput}
placeholder ="Try: go, iku, 行く, home, ie..."
class ="w-full rounded-lg border border-gray-300 px-4 py-2 focus:border-transparent focus:ring-2 focus:ring-blue-500"
/>
</div >
<div >
<label for ="threshold" class ="mb-2 block text-sm font-medium" >
Threshold: {search.threshold.toFixed(2)}
</label >
<input
id ="threshold"
type ="range"
min ="0"
max ="1"
step ="0.1"
value ={search.threshold}
oninput ={handleThresholdChange}
class ="w-full"
/>
<p class ="mt-1 text-xs text-gray-600" > Lower values = more results (less strict matching)</p >
</div >
</div >
<div >
<h2 class ="mb-4 text-xl font-semibold" >
Results ({search.results.length})
</h2 >
{#if search.results.length > 0}
<div class ="grid gap-3" >
{#each search.results as result, i (i)}
<div class ="rounded-lg border border-gray-200 p-4 transition-shadow hover:shadow-md" >
<div class ="flex items-center justify-between" >
<div >
<p class ="text-2xl font-bold text-gray-900" > {result.item.japanese}</p >
<p class ="text-lg text-gray-600" > {result.item.romaji}</p >
<p class ="text-gray-700" > {result.item.english}</p >
</div >
<div class ="text-right" >
<span
class ="inline-block rounded-full bg-blue-100 px-3 py-1 text-sm font-medium text-blue-800"
>
Score: {(1 - (result.score ?? 0)).toFixed(3)}
</span >
</div >
</div >
</div >
{/each}
</div >
{:else if search.searchQuery}
<p class ="text-gray-500 italic" > No results found. Try adjusting the threshold.</p >
{:else}
<p class ="text-gray-500 italic" > Start typing to search...</p >
{/if}
</div >
</div >
Advanced Advanced Fuzzy Search Example Start typing to search...
Click on a result to see details
Favorites (0) No favorites yet
Copy <script lang ="ts" >
import { useFuzzySearch, type DataItem } from 'flexilexi' ;
import data from '../../data/japanese-data.json' ;
const search = useFuzzySearch ({
data,
keys : ['japanese' , 'romaji' , 'english' ],
thresholdValue : 0.5
});
let selectedItem = $state<DataItem | null >(null );
let favorites = $state<DataItem []>([]);
let searchValue = $state('' );
function selectItem (item: DataItem ) {
selectedItem = item;
}
function toggleFavorite (item: DataItem ) {
if (favorites.some ((f ) => f.japanese === item.japanese )) {
favorites = favorites.filter ((f ) => f.japanese !== item.japanese );
} else {
favorites = [...favorites, item];
}
}
function isFavorite (item: DataItem ) {
return favorites.some ((f ) => f.japanese === item.japanese );
}
function handleSearchInput (event: Event ) {
const target = event.target as HTMLInputElement ;
searchValue = target.value ;
search.setSearchQuery (searchValue);
}
const hasResults = $derived(search.results .length > 0 );
const resultCount = $derived(search.results .length );
</script >
<div class ="mx-auto max-w-6xl p-6" >
<h1 class ="mb-6 text-3xl font-bold" > Advanced Fuzzy Search Example</h1 >
<div class ="grid gap-6 lg:grid-cols-3" >
<div class ="lg:col-span-2" >
<div class ="mb-4" >
<input
value ={searchValue}
oninput ={handleSearchInput}
placeholder ="Search Japanese, romaji, or English..."
class ="w-full rounded-lg border border-gray-300 px-4 py-3 text-lg focus:border-transparent focus:ring-2 focus:ring-blue-500"
/>
<div class ="mt-2 text-sm text-gray-600" >
Found {resultCount}
{resultCount === 1 ? 'result' : 'results'}
</div >
</div >
{#if hasResults}
<div class ="space-y-2" >
{#each search.results as result, i (i)}
<div
class ="flex items-center justify-between rounded-lg border border-gray-200 p-4 transition-all hover:border-blue-300 hover:shadow-md"
class:ring-2 ={selectedItem?.japanese === result.item.japanese}
class:ring-blue-500 ={selectedItem?.japanese === result.item.japanese}
>
<button onclick ={() => selectItem(result.item)} class="flex-1 text-left">
<div class ="text-xl font-bold text-gray-900" > {result.item.japanese}</div >
<div class ="text-base text-gray-600" > {result.item.romaji}</div >
<div class ="text-sm text-gray-500" > {result.item.english}</div >
</button >
<div class ="ml-4 flex items-center gap-3" >
<span class ="rounded-full bg-blue-100 px-3 py-1 text-xs font-medium text-blue-800" >
{(1 - (result.score ?? 0)).toFixed(2)}
</span >
<button
onclick ={() => toggleFavorite(result.item)}
class="text-2xl transition-transform hover:scale-110"
aria-label={isFavorite(result.item)
? 'Remove from favorites'
: 'Add to favorites'}
>
{isFavorite(result.item) ? '★' : '☆'}
</button >
</div >
</div >
{/each}
</div >
{:else if searchValue}
<div
class ="rounded-lg border-2 border-dashed border-gray-300 p-8 text-center text-gray-500"
>
No results found for "{searchValue}"
</div >
{:else}
<div
class ="rounded-lg border-2 border-dashed border-gray-300 p-8 text-center text-gray-500"
>
Start typing to search...
</div >
{/if}
</div >
<div class ="space-y-6" >
{#if selectedItem}
<div class ="rounded-lg border border-blue-200 bg-blue-50 p-4" >
<h2 class ="mb-3 text-lg font-semibold text-blue-900" > Selected Item</h2 >
<div class ="space-y-2" >
<div >
<span class ="text-xs font-medium text-blue-700 uppercase" > Japanese</span >
<div class ="text-2xl font-bold text-blue-900" > {selectedItem.japanese}</div >
</div >
<div >
<span class ="text-xs font-medium text-blue-700 uppercase" > Romaji</span >
<div class ="text-lg text-blue-800" > {selectedItem.romaji}</div >
</div >
<div >
<span class ="text-xs font-medium text-blue-700 uppercase" > English</span >
<div class ="text-blue-800" > {selectedItem.english}</div >
</div >
</div >
</div >
{:else}
<div class ="rounded-lg border border-gray-200 bg-gray-50 p-4 text-center text-gray-500" >
Click on a result to see details
</div >
{/if}
<div class ="rounded-lg border border-gray-200 bg-white p-4" >
<h2 class ="mb-3 text-lg font-semibold text-gray-900" >
Favorites ({favorites.length})
</h2 >
{#if favorites.length > 0}
<div class ="space-y-2" >
{#each favorites as fav, i (i)}
<div
class ="flex items-center justify-between rounded border border-gray-200 bg-gray-50 p-3"
>
<div class ="flex-1" >
<div class ="font-bold text-gray-900" > {fav.japanese}</div >
<div class ="text-sm text-gray-600" > {fav.romaji}</div >
</div >
<button
onclick ={() => toggleFavorite(fav)}
class="text-xl text-yellow-500 transition-transform hover:scale-110"
aria-label="Remove from favorites"
>
★
</button >
</div >
{/each}
</div >
{:else}
<p class ="text-center text-sm text-gray-500" > No favorites yet</p >
{/if}
</div >
</div >
</div >
</div >
Single Object Data FuzzySearch works with object dictionaries , not just arrays
What is a Single Object? Instead of an array of objects, you can pass a single object where keys map to values.
FuzzySearch automatically converts it into a searchable format.
Perfect for: Dictionaries: Word definitions, glossaries Translations: Key-value translation pairs Configuration: Settings and their descriptions Simple lookups: Any key-to-value mapping Format: FuzzySearch converts {'key': 'value'} into [{'key': '...', 'value': '...'}, ...] automatically.
Copy <script lang ="ts" >
import englishData from '../../data/english-data.json' ;
import { Fuzzy } from 'flexilexi' ;
</script >
<Fuzzy data ={englishData} divClass ="p-4" div2Class ="p-4" />
Sample data
{
"abacus": "A counting device that uses beads on rods to perform arithmetic operations.",
"amiable": "Having or displaying a friendly and pleasant manner.",
"altruistic": "Showing a selfless concern for the well-being of others.",
"benevolent": "Well-meaning and kindly."
...
}
Sample data
[
{
"japanese": "行く",
"romaji": "iku",
"english": "go"
},
{
"japanese": "見る",
"romaji": "miru",
"english": "see, look at"
},
{
"japanese": "多い",
"romaji": "ooi",
"english": "a lot of, many"
},
...
]