%

Hugo Search: an internal search engine (JQueryUI autocomplete)

Article published the ; modified the
3 minutes to read

This article has 506 words.
RAW source of the article:
Commit version: 5ed7c38

Description

Adding a function search into static website made with Hugo can be done in differents ways.

We will code this simply with JQuery+UI, in few minutes.

We will use the Hugo site.Pages variable, and the JQueryUI autocomplete() method.

I assume you known how to add correctly the both JQuery and JQueryUI librairies on your site.

Codes

JQueryUI

As explain into the description section, we use the events of the method autocomplete(). We build the $projects variable to iterate over the Hugo $pages variable with the Hugo range function.

The JQuery code:

<script>
$(function() {
    var projects = [
        {{- range site.Pages -}}
            {{- $url := .RelPermalink -}}
            {{- $title := .LinkTitle -}}
        {
            value: "{{ $title }}",
			label: "{{- if eq $url $baseURL }}{{ site.Params.description }}{{ else if in $url "tags" }}{{- T "pageListTitle" }}{{ $title }}{{ else }}{{- safeHTML .Params.description -}}{{ end -}}",
            url:"{{ $url }}"
        },
        {{- end -}}
    ];
    $("#search").autocomplete({
		minLength: 0,
        source: projects,
        focus: function( event, ui ) {
			$("#search").val( ui.item.label );
			return false;
        },
        select: function( event, ui ) {
			$("#search").val( ui.item.label );
			$("#replyer").val( ui.item.value );
			return false;
        }
    })
    .data('ui-autocomplete')._renderItem = function(ul, item) {
        return $('<li>')
        .append('<a href="' + item.url + '" alt="'+ item.label + '">' + item.value + '</a>' )
        .appendTo(ul);
    };
});
</script>

HTML

And for the simplest code HTML, we use two elements input as:

<input class="form-control" id="search" placeholder="{{ T "searchHolderTitle" }}">
<input aria-hidden="true" id="replyer" class="hidden">
  • the first catch the searched text
  • the second return all found titles, and in the background the equivalent URL.
  • the syntax {{ i18n "searchHolderTitle" }} exists for the multilanguage context on this website; You can replace with your personal text.

TL;DR

The fully code:

<div id="search">
    <input class="form-control" id="search" placeholder="{{ T "searchHolderTitle" }}">
    <input aria-hidden="true" id="replyer" class="hidden">
    {{- $baseURL := site.BaseURL | absLangURL -}}
    <!-- Javascript -->
<script>
$(function() {
    var projects = [
        {{- range site.Pages -}}
            {{- $url := .RelPermalink -}}
            {{- $title := .LinkTitle -}}
        {
            value: "{{ $title }}",
			label: "{{- if eq $url $baseURL }}{{ site.Params.description }}{{ else if in $url "tags" }}{{- T "pageListTitle" }}{{ $title }}{{ else }}{{- safeHTML .Params.description -}}{{ end -}}",
            url:"{{ $url }}"
        },
        {{- end -}}
    ];
    $("#search").autocomplete({
		minLength: 0,
        source: projects,
        focus: function( event, ui ) {
			$("#search").val( ui.item.label );
			return false;
        },
        select: function( event, ui ) {
			$("#search").val( ui.item.label );
			$("#replyer").val( ui.item.value );
			return false;
        }
    })
    .data('ui-autocomplete')._renderItem = function(ul, item) {
        return $('<li>')
        .append('<a href="' + item.url + '" alt="'+ item.label + '">' + item.value + '</a>' )
        .appendTo(ul);
    };
});
</script>
</div>

Demo

Voilà ! In few minutes, an “internal search engine” is born on your static website Hugo.

See, the search holder on the menu navigation, at top right side ;)


Documentation

Others Documentations