#Add search component with content collections

1 messages · Page 1 of 1 (latest)

dapper pawn
#

Hello. I would like to add a live search component for my website, similar to the one on the MDN website (https://developer.mozilla.org/en-US/).

This is what I have so far:

---
import { SITE_TITLE } from "../consts";
import { getCollection } from 'astro:content';

async function searchPost(term) {
  const posts = (await getCollection('blog')).filter(
      article => article.data.title.includes(term)
  );

  return posts
} 
---

<header>
  <div class="container">
    <h2>
      <a href="/">{SITE_TITLE}</a>
    </h2>
    <label for="search-articles">Search for an article:</label>
    <input type="search" id="search-articles" placeholder="first post" />
  </div>
</header>

<script>
  const searchArticles = document.querySelector("#search-articles");

  searchArticles.addEventListener("change", event => {
    searchPost(event.target.value);
  })
</script>

I'm not sure how I would effectively create the search functionality. Can someone help?

#

(I know how I could do it with a search button, but I want it to update whenever the value of the input changes)

ripe iris
dapper pawn
ripe iris
#

I do

#

but pagefind doesn't mind what you use, as long as it's a static output website

#

and it will index every page (unless explicitly excluded)

dapper pawn
#

Alright, I'll try it. Thank you 🙂

signal heron
#

I second that, pagefind is awesome

dapper pawn
#
<script>
  import { getCollection } from 'astro:content';

  let searchTerm = "";
</script>

<label for="search-articles">Search for an article:</label>
<input type="search" id="search-articles" placeholder="first post" bind:value={searchTerm} />

{#if searchTerm.trim()}
  {#await getCollection("blog")}
    <p>Searching...</p>
  {:then posts}
    {@const filteredPosts = posts.filter(post => post.data.title.toLowerCase().includes(searchTerm.toLowerCase().trim()))}

    {#if filteredPosts.length > 0}
      <ul>
        {#each filteredPosts as post}
          <li>
            <a href={`/blog/${post.slug}/`}>{post.data.title}</a>
          </li>
        {/each}
      </ul>
    {:else}
      <p>No results found!</p>
    {/if}
  {:catch error}
    <p>An error occured!</p>
  {/await}
{/if}
ripe iris
#

awesome! that works too, especially if you only want to search frontmatter on a post. I'm assuming this is using SSR?

dapper pawn
ripe iris
#

oh really? I didn't think getCollection would work in a production static site?

dapper pawn
#

I'm not sure to be honest

#

I don't know If I'd rather use pagefind or svelte