Skip to content

Instantly share code, notes, and snippets.

@IronGhost63
Last active September 16, 2025 08:30
Show Gist options
  • Select an option

  • Save IronGhost63/da52a0d8b038d6d378a27df3efb782f8 to your computer and use it in GitHub Desktop.

Select an option

Save IronGhost63/da52a0d8b038d6d378a27df3efb782f8 to your computer and use it in GitHub Desktop.
Fuzzy Search inside JSON data using Fuse.js
<?php
/**
* File use to generate gzipped JSON data
*/
$data = connect_and_fetch_data();
$formatted = array_map( function( $item ) {
// Format data anyway you want. Then adjust 'keys' option in Fuse.js accordingly
$item = format_your_data( $item );
return $item;
}, $data );
$json = json_encode( $formatted );
// use `gzencode( $json )` to compress strings
file_put_contents( './data.json', gzencode( $json ) );
[
{
"en": {
"post_title": "Hello World",
"meta": {
"categories": ["sample", "new"],
"description": "Lorem ipsum dolor sit amet"
}
},
"th": {
"post_title": "สวัสดีโลก",
"meta": {
"categories": ["ทดสอบ", "ใหม่"],
"description": "โลเร็มยิปซัมโดโลซิทเอเม็ท"
}
}
},
{
"en": {
"post_title": "Foo Bar",
"meta": {
"categories": ["sample", "new"],
"description": "Bar Baz"
}
},
"th": {
"post_title": "ฟูบาร์",
"meta": {
"categories": ["ทดสอบ", "ใหม่"],
"description": "บาร์บาส"
}
}
}
]
import Fuse from 'fuse.js';
/*
Context: Our data are rarely change not just over two hundrends item. So to acheive instant search, we compile the list of content and all searchable posts (along with their ACF data) and put it inside gziped JSON.
*/
export default async () => {
// Fetch Data
const jsonUrl = `https://parth-to-json/sample.json`;
const response = await fetch( jsonUrl );
// Decompress GZiped data.
const ds = new DecompressionStream("gzip");
const decompressedStream = response.body.pipeThrough(ds);
const decompressedText = await new Response(decompressedStream).text();
// Make sure data is Array of Object
const data = JSON.parse( decompressedText );
const newArray = [...Object.values(data)];
// Define which properties to search under `keys` property
const searchEngine = new Fuse( newArray, {
includeScore: true,
keys: [
'en.post_title',
'en.meta.description',
'th.post_title',
'th.meta.description',
} );
const searchBox = document.querySelector('.search-input');
// Listen to keyup event, search instantly while typing
searchBox.addEventListener('keyup', (e) => {
const keyword = e.target.value;
const results = searchEngine.search(keyword, {
limit: 10
});
results.map( (row) => {
// matched object will be in `item` property
const data = row.item;
// do whatever you want with the result.
displayResults( data );
});
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment