Building a Simple Search Feature in Svelte
Svelte’s reactivity makes it straightforward to update the UI when component state changes. In this example, we will build a small product search: as the user types, matching items appear immediately.
1. Complete Example
Create src/routes/+page.svelte:
<script lang="ts">
let query = "";
let products = ["Laptop", "Mouse", "Keyboard", "Monitor", "Printer"];
let results: string[] = [];
function searchProducts(q: string) {
if (q.trim() === "") {
results = [];
} else {
results = products.filter((p) =>
p.toLowerCase().includes(q.toLowerCase())
);
}
}
// Reactive statement: runs whenever query changes
$: searchProducts(query);
</script>
<input bind:value={query} placeholder="Search products..." />
<ul>
{#if query.trim() !== ""}
{#if results.length > 0}
{#each results as item}
<li>{item}</li>
{/each}
{:else}
<li>No results</li>
{/if}
{/if}
</ul>2. How It Works
The component has three pieces of state:
let query = "";
let products = ["Laptop", "Mouse", "Keyboard", "Monitor", "Printer"];
let results: string[] = [];query stores the search text, products contains the source data, and results contains the filtered items.
The search function performs a case-insensitive substring match:
function searchProducts(q: string) {
if (q.trim() === "") {
results = [];
} else {
results = products.filter((p) =>
p.toLowerCase().includes(q.toLowerCase())
);
}
}The reactive statement reruns the function whenever query changes:
$: searchProducts(query);The input is bound directly to query:
<input bind:value={query} placeholder="Search products..." />And the template renders matching items or a fallback message:
{#if results.length > 0}
{#each results as item}
<li>{item}</li>
{/each}
{:else}
<li>No results</li>
{/if}3. Example Behavior
- Type
lap→ Laptop appears. - Type
mo→ Mouse and Monitor appear. - Type text that matches nothing → No results appears.
- Clear the input → the result list disappears.
Conclusion
Svelte reactive statements can make small UI features such as local search concise and easy to follow. The same idea can be extended to table filtering, autocomplete, or API-backed search, although remote searches usually also need debouncing and request-state handling.
This example uses Svelte’s legacy $: reactive-statement syntax. In a new Svelte 5 application using runes mode, use the equivalent runes-based reactivity APIs.