nkdAgility / NKDAgility.com

Other
1 stars 0 forks source link

Search #11

Open MrHinsh opened 1 month ago

MrHinsh commented 1 month ago

To enable your Hugo static site to have a searchable list of resources, you can implement client-side search functionality. Since Hugo is a static site generator, search functionality typically relies on JavaScript (client-side) rather than a traditional server-side search.

Here are a few approaches to add search functionality to your Hugo site:

Option 1: Use Lunr.js for Client-Side Search

Lunr.js is a small JavaScript library that can be used to create a search index directly in the browser for fast client-side searching. Here's how you can integrate it into your Hugo site:

Step 1: Install the Lunr.js Script

  1. Download the Lunr.js library from Lunr.js GitHub or include it via CDN.

In your Hugo theme's layouts/partials/head.html file, add the Lunr.js script:

<script src="https://cdn.jsdelivr.net/npm/lunr/lunr.min.js"></script>

Step 2: Generate a Search Index File

  1. Create a custom layout to generate a JSON search index that will be used by Lunr.js.

In layouts/_default/, create a file called index.json:

{{- $.Scratch.Add "index" slice -}}
{{- range where .Site.Pages "Type" "in" (slice "resources" "blog" "newsletters" "videos" "podcasts") -}}
  {{- $.Scratch.Add "index" (dict "title" .Title "summary" .Params.description "content" .Plain "url" .Permalink) -}}
{{- end -}}
{{- $.Scratch.Get "index" | jsonify -}}

This will create a JSON file at /index.json that contains all of the content from your specified sections (e.g., blog, newsletters, videos, podcasts) which Lunr.js can index.

Step 3: Add the Search Box

Add an HTML search input to your site (e.g., in the header.html or in a partial):

<input type="text" id="search-input" placeholder="Search resources...">
<div id="search-results"></div>

Step 4: Create a JavaScript Function to Perform the Search

In your site’s /static/js/ directory, create a search.js file to handle the search functionality:

const searchInput = document.getElementById('search-input');
const searchResults = document.getElementById('search-results');

fetch('/index.json')
  .then(response => response.json())
  .then(pages => {
    const idx = lunr(function () {
      this.ref('url');
      this.field('title');
      this.field('summary');
      this.field('content');

      pages.forEach(page => {
        this.add(page);
      });
    });

    searchInput.addEventListener('input', function () {
      const query = searchInput.value.trim();
      const results = idx.search(query);

      searchResults.innerHTML = results.map(result => {
        const page = pages.find(p => p.url === result.ref);
        return `<a href="${page.url}">${page.title}</a>`;
      }).join('');
    });
  });

Include the script in your head.html:

<script src="/js/search.js"></script>

Step 5: Style the Search Results

In your static/css/style.css, you can add some basic styles for the search box and results:

#search-results {
  margin-top: 10px;
}

#search-results a {
  display: block;
  padding: 5px;
  background: #f8f8f8;
  border: 1px solid #ddd;
  text-decoration: none;
  margin-bottom: 5px;
}

#search-results a:hover {
  background: #ececec;
}

Step 6: Test the Search

Run Hugo locally and verify that your search functionality is working:

hugo server

Option 2: Use Fuse.js for Fuzzy Search

Fuse.js is another lightweight JavaScript library that offers fuzzy search capabilities. It works similarly to Lunr.js but is more forgiving with typographical errors in search queries. You can follow a very similar implementation as with Lunr.js, but swap out the JavaScript library for Fuse.js.

Include Fuse.js from the CDN:

<script src="https://cdn.jsdelivr.net/npm/fuse.js@6.4.6/dist/fuse.min.js"></script>

The rest of the steps remain similar to Lunr.js, except for the search logic in search.js.

Option 3: Use a Hosted Search Service (Optional)

If you want a more advanced or scalable search functionality, you can use a hosted search service like Algolia:

  1. Set up an Algolia account and create a search index for your content.
  2. Use the Algolia API to index your Hugo content, and implement the search functionality using their search client.

This option is more complex and may involve recurring costs, but it's highly scalable for large sites.

Conclusion:

For most Hugo static sites, Lunr.js or Fuse.js are the best options for client-side search as they are simple to implement, work without needing a server, and provide fast search results for medium-sized websites.

Would you like help with a specific approach or additional customization?