Improve search functionality with Fuse.js for better accuracy and UX (#76)

* Improve search functionality with Fuse.js

* Centralized social media links in `data/index.ts`

* Fix formatting

Signed-off-by: nurRiyad <asadnurriyad@gmail.com>

* Update dependency

Signed-off-by: nurRiyad <asadnurriyad@gmail.com>

* Fix formatting

Signed-off-by: nurRiyad <asadnurriyad@gmail.com>

---------

Signed-off-by: nurRiyad <asadnurriyad@gmail.com>
Co-authored-by: nurRiyad <asadnurriyad@gmail.com>
This commit is contained in:
Nicolhetti
2025-01-10 17:30:03 -03:00
committed by GitHub
parent 0c17603459
commit 8fc4675421
6 changed files with 50 additions and 27 deletions

View File

@@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { footerData } from '~/data' import { footerData, socialLinks } from '~/data'
</script> </script>
<template> <template>
@@ -12,7 +12,7 @@ import { footerData } from '~/data'
</p> </p>
<div class="my-3 space-x-3 pb-3"> <div class="my-3 space-x-3 pb-3">
<NuxtLink <NuxtLink
to="https://github.com/nurRiyad" :to="socialLinks.githubLink"
target="_blank" target="_blank"
class="p-2 bg-gray-300 text-gray-800 rounded-md dark:bg-sky-700 dark:text-[#F1F2F4]" class="p-2 bg-gray-300 text-gray-800 rounded-md dark:bg-sky-700 dark:text-[#F1F2F4]"
aria-label="Github" aria-label="Github"
@@ -20,7 +20,7 @@ import { footerData } from '~/data'
<Icon name="fa:github" size="1em" /> <Icon name="fa:github" size="1em" />
</NuxtLink> </NuxtLink>
<NuxtLink <NuxtLink
to="https://www.linkedin.com/in/nur-riyad/" :to="socialLinks.linkedinLink"
target="_blank" target="_blank"
class="p-2 bg-gray-300 text-gray-800 rounded-md dark:bg-sky-700 dark:text-[#F1F2F4]" class="p-2 bg-gray-300 text-gray-800 rounded-md dark:bg-sky-700 dark:text-[#F1F2F4]"
aria-label="LinkedIn" aria-label="LinkedIn"
@@ -28,7 +28,7 @@ import { footerData } from '~/data'
<Icon name="fa:linkedin-square" size="1em" /> <Icon name="fa:linkedin-square" size="1em" />
</NuxtLink> </NuxtLink>
<NuxtLink <NuxtLink
to="https://twitter.com/qdnvubp" :to="socialLinks.twitterLink"
target="_blank" target="_blank"
class="p-2 bg-gray-300 text-gray-800 rounded-md dark:bg-sky-700 dark:text-[#F1F2F4]" class="p-2 bg-gray-300 text-gray-800 rounded-md dark:bg-sky-700 dark:text-[#F1F2F4]"
aria-label="Twitter" aria-label="Twitter"
@@ -36,7 +36,7 @@ import { footerData } from '~/data'
<Icon name="fa:twitter-square" size="1em" /> <Icon name="fa:twitter-square" size="1em" />
</NuxtLink> </NuxtLink>
<NuxtLink <NuxtLink
to="https://stackoverflow.com/users/16781395/nur-riyad" :to="socialLinks.stackoverflowLink"
target="_blank" target="_blank"
class="p-2 bg-gray-300 text-gray-800 rounded-md dark:bg-sky-700 dark:text-[#F1F2F4]" class="p-2 bg-gray-300 text-gray-800 rounded-md dark:bg-sky-700 dark:text-[#F1F2F4]"
aria-label="StackOverflow" aria-label="StackOverflow"

View File

@@ -48,6 +48,13 @@ export const seoData = {
mailAddress: 'asadnurriyad@gmail.com', mailAddress: 'asadnurriyad@gmail.com',
} }
export const socialLinks = {
githubLink: 'https://github.com/nurRiyad',
linkedinLink: 'https://www.linkedin.com/in/nur-riyad/',
twitterLink: 'https://twitter.com/qdnvubp',
stackoverflowLink: 'https://stackoverflow.com/users/16781395/nur-riyad',
}
export const siteMetaData = [ export const siteMetaData = [
{ {
name: 'description', name: 'description',

View File

@@ -31,6 +31,7 @@
"@vueuse/nuxt": "^10.9.0", "@vueuse/nuxt": "^10.9.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"feed": "^4.2.2", "feed": "^4.2.2",
"fuse.js": "^7.0.0",
"nuxt": "^3.14.159", "nuxt": "^3.14.159",
"nuxt-icon": "^0.6.8", "nuxt-icon": "^0.6.8",
"nuxt-og-image": "^3.0.0-rc.38", "nuxt-og-image": "^3.0.0-rc.38",

View File

@@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { aboutPage, footerData, navbarData } from '~/data' import { aboutPage, footerData, navbarData, socialLinks } from '~/data'
useHead({ useHead({
title: 'About', title: 'About',
@@ -31,7 +31,7 @@ defineOgImageComponent('About', {
<div class="my-3 space-x-2 md:space-x-3 pb-10"> <div class="my-3 space-x-2 md:space-x-3 pb-10">
<NuxtLink <NuxtLink
to="https://github.com/nurRiyad" :to="socialLinks.githubLink"
target="_blank" target="_blank"
class="px-2 py-1 lg:px-3 lg:py-2 bg-gray-300 text-gray-800 rounded-md dark:bg-slate-700 dark:text-[#F1F2F4]" class="px-2 py-1 lg:px-3 lg:py-2 bg-gray-300 text-gray-800 rounded-md dark:bg-slate-700 dark:text-[#F1F2F4]"
aria-label="Github" aria-label="Github"
@@ -39,7 +39,7 @@ defineOgImageComponent('About', {
<Icon name="fa:github" size="1em" /> <Icon name="fa:github" size="1em" />
</NuxtLink> </NuxtLink>
<NuxtLink <NuxtLink
to="https://www.linkedin.com/in/nur-riyad/" :to="socialLinks.linkedinLink"
target="_blank" target="_blank"
class="px-2 py-1 lg:px-3 lg:py-2 bg-gray-300 text-gray-800 rounded-md dark:bg-slate-700 dark:text-[#F1F2F4]" class="px-2 py-1 lg:px-3 lg:py-2 bg-gray-300 text-gray-800 rounded-md dark:bg-slate-700 dark:text-[#F1F2F4]"
aria-label="LinkedIn" aria-label="LinkedIn"
@@ -47,7 +47,7 @@ defineOgImageComponent('About', {
<Icon name="fa:linkedin-square" size="1em" /> <Icon name="fa:linkedin-square" size="1em" />
</NuxtLink> </NuxtLink>
<NuxtLink <NuxtLink
to="https://twitter.com/qdnvubp" :to="socialLinks.twitterLink"
target="_blank" target="_blank"
class="px-2 py-1 lg:px-3 lg:py-2 bg-gray-300 text-gray-800 rounded-md dark:bg-slate-700 dark:text-[#F1F2F4]" class="px-2 py-1 lg:px-3 lg:py-2 bg-gray-300 text-gray-800 rounded-md dark:bg-slate-700 dark:text-[#F1F2F4]"
aria-label="Twitter" aria-label="Twitter"
@@ -55,7 +55,7 @@ defineOgImageComponent('About', {
<Icon name="fa:twitter-square" size="1em" /> <Icon name="fa:twitter-square" size="1em" />
</NuxtLink> </NuxtLink>
<NuxtLink <NuxtLink
to="https://stackoverflow.com/users/16781395/nur-riyad" :to="socialLinks.stackoverflowLink"
target="_blank" target="_blank"
class="px-2 py-1 lg:px-3 lg:py-2 bg-gray-300 text-gray-800 rounded-md dark:bg-slate-700 dark:text-[#F1F2F4]" class="px-2 py-1 lg:px-3 lg:py-2 bg-gray-300 text-gray-800 rounded-md dark:bg-slate-700 dark:text-[#F1F2F4]"
aria-label="StackOverflow" aria-label="StackOverflow"

View File

@@ -1,4 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import Fuse from 'fuse.js'
const { data } = await useAsyncData('home', () => queryContent('/blogs').sort({ _id: -1 }).find()) const { data } = await useAsyncData('home', () => queryContent('/blogs').sort({ _id: -1 }).find())
const elementPerPage = ref(5) const elementPerPage = ref(5)
@@ -23,26 +25,28 @@ const formattedData = computed(() => {
) )
}) })
const fuse = computed(() => {
return new Fuse(formattedData.value, {
keys: ['title', 'description'],
threshold: 0.4,
includeScore: false,
})
})
const searchData = computed(() => { const searchData = computed(() => {
return ( if (!searchTest.value.trim()) {
formattedData.value.filter((data) => { return formattedData.value
const lowerTitle = data.title.toLocaleLowerCase() }
if (lowerTitle.search(searchTest.value) !== -1) return true
else return false const results = fuse.value.search(searchTest.value)
}) || [] return results.map((result) => result.item)
)
}) })
const paginatedData = computed(() => { const paginatedData = computed(() => {
return ( const startInd = (pageNumber.value - 1) * elementPerPage.value
searchData.value.filter((data, idx) => { const endInd = pageNumber.value * elementPerPage.value
const startInd = (pageNumber.value - 1) * elementPerPage.value
const endInd = pageNumber.value * elementPerPage.value - 1
if (idx >= startInd && idx <= endInd) return true return searchData.value.slice(startInd, endInd)
else return false
}) || []
)
}) })
function onPreviousPageClick() { function onPreviousPageClick() {
@@ -51,8 +55,7 @@ function onPreviousPageClick() {
const totalPage = computed(() => { const totalPage = computed(() => {
const ttlContent = searchData.value.length || 0 const ttlContent = searchData.value.length || 0
const totalPage = Math.ceil(ttlContent / elementPerPage.value) return Math.ceil(ttlContent / elementPerPage.value)
return totalPage
}) })
function onNextPageClick() { function onNextPageClick() {

12
pnpm-lock.yaml generated
View File

@@ -55,6 +55,9 @@ importers:
feed: feed:
specifier: ^4.2.2 specifier: ^4.2.2
version: 4.2.2 version: 4.2.2
fuse.js:
specifier: ^7.0.0
version: 7.0.0
nuxt: nuxt:
specifier: ^3.14.159 specifier: ^3.14.159
version: 3.14.159(@parcel/watcher@2.5.0)(@types/node@22.9.0)(eslint@9.14.0(jiti@2.4.0))(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.24.4)(terser@5.36.0)(typescript@5.6.3)(vite@5.4.10(@types/node@22.9.0)(terser@5.36.0)) version: 3.14.159(@parcel/watcher@2.5.0)(@types/node@22.9.0)(eslint@9.14.0(jiti@2.4.0))(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.24.4)(terser@5.36.0)(typescript@5.6.3)(vite@5.4.10(@types/node@22.9.0)(terser@5.36.0))
@@ -4228,6 +4231,13 @@ packages:
integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==, integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==,
} }
fuse.js@7.0.0:
resolution:
{
integrity: sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==,
}
engines: { node: '>=10' }
gauge@3.0.2: gauge@3.0.2:
resolution: resolution:
{ {
@@ -11785,6 +11795,8 @@ snapshots:
function-bind@1.1.2: {} function-bind@1.1.2: {}
fuse.js@7.0.0: {}
gauge@3.0.2: gauge@3.0.2:
dependencies: dependencies:
aproba: 2.0.0 aproba: 2.0.0