Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Search #11

Open
MrHinsh opened this issue Sep 15, 2024 · 0 comments
Open

Search #11

MrHinsh opened this issue Sep 15, 2024 · 0 comments
Assignees
Labels
question Further information is requested

Comments

@MrHinsh
Copy link
Member

MrHinsh commented Sep 15, 2024

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?

@MrHinsh MrHinsh self-assigned this Oct 25, 2024
@MrHinsh MrHinsh added enhancement New feature or request question Further information is requested and removed enhancement New feature or request labels Oct 25, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

1 participant