{"title":"Search bar in Sveltekit","url":"https://seanbehan.ca/posts/svelte-search","description":"The fuzzy search on this site, built with fuse.js.","author":"Sean Behan","published":"2023-12-06T20:29:41.990Z","updated":null,"draft":false,"tags":["cloudflare","javascript","serverless","svelte","sveltekit","typescript"],"readingMinutes":1,"image":null,"sections":[{"id":"introduction","text":"Introduction","level":2},{"id":"implementing-the-search-bar","text":"Implementing the Search Bar","level":2},{"id":"how-it-works","text":"How it Works","level":2}],"content_format":"text/markdown","content_url":"https://seanbehan.ca/posts/svelte-search.md","content":"### Introduction\n\nIn this post I'm going to show you how I made the search bar on the posts page\n\nand main page of my website.\n\n### Implementing the Search Bar\n\nI used a library called `fuse.js` for fuzzy searching for titles, here's how it\n\nworks.\n\n```typescript\n<script lang=\"ts\">\n\timport { Heading } from 'flowbite-svelte';\n\timport Post from '$lib/components/Post.svelte';\n\timport Fuse from 'fuse.js';\n\timport { afterUpdate } from 'svelte';\n\texport let posts: { path: string; meta: { title: string; date: string } }[];\n\tlet query = '*';\n\tlet results = posts;\n\tconst options = { keys: ['meta.title'] };\n\tconst fuse = new Fuse(posts, options);\n\tafterUpdate(() => {\n\t\tlet results_ = fuse.search(query);\n\t\tresults = results_.map((result) => ({ path: result.item.path, meta: result.item.meta }));\n\t});\n</script>\n\n<Heading\n\ttag=\"h4\"\n\tstyle=\"display: inline\"\n\tclass=\"ml-8 my-4 text-secondary dark:text-dark-secondary w-auto\">Posts</Heading\n>\n<input class=\"text-secondary\" bind:value={query} />\n<ul>\n\t{#each results as post}\n\t\t<Post {post} />\n\t{/each}\n\t{#if results.length === 0}\n\t\t{#each posts as post}\n\t\t\t<Post {post} />\n\t\t{/each}\n\t{/if}\n</ul>\n```\n\n### How it Works\n\nYou can see I initialize the query to `'*'`. All this really does is sets the\n\nsearch field to `*` instead of being empty. Then in the input element I bind to\n\nthe value of query so that when the user types in the field the value of query\n\nwill change.\n\nI do some more initialization of `fuse.js` to search and then I register\n\n`afterUpdate()`. This allows me to search only when the page changes.\n\nFinally I added some logic to display all the posts if there are no results,\n\nlike for example when the page loads.\n\nAll this together looks like the search bar you see on `/posts` and `/`.\n"}