How to add search to a static site

How to add search to a static site generated with Hugo…

… using lunr.js

Since version 0.20 Hugo has a build in capability to create a (customized) index file of available markdown documents down below the content directory tree.

Once this index file is available, we can use lunr.js - a jquery based javascript - to implement a search functionality. The search result pops up instantly, while the user is typing… - pretty neat!

What follows is a brief description to get the whole thing up and running:

Configuration setting (config.toml)

  • Make sure, to have the most recent hugo version installed, at least V0.20 is requred. You might want to run: hugo version just to be sure.

  • Add the following to your config.toml configuration file:

    [outputs]
    home = [ "HTML", "RSS", "JSON"]
        
    
  • Note: Make shure to locate the required index.json file in the layouts folder. Once the file exists, hugo is going to dump the index to file.

    The index.json file looks like:

    [{{ range $index, $page := .Site.Pages }}
    {{- if ne $page.Type "json" -}}
    {{- if and $index (gt $index 0) -}},{{- end }}
    {
        "uri": "{{ $page.Permalink }}",
        "title": "{{ htmlEscape $page.Title}}",
        "tags": [{{ range $tindex, $tag := $page.Params.tags }}{{ if $tindex }}, {{ end }}"{{ $tag| htmlEscape }}"{{ end }}],
        "description": "{{ htmlEscape .Description}}",
        "content": {{$page.Plain | jsonify}}
    }
    {{- end -}}
    {{- end -}}]
    
    

Once this is done, hugo generates a lunrjs index.json at the root of your public folder. If you encounter some problems run: hugo --verbose and check messages and warnings.

Web site configuration:

  • ../layouts/partials/header.html

    Typically, that’s where the css files are:

    <head>
    ...
    {{ if not .Site.Params.disableSearch }}
        <link href="{{ .Site.BaseURL }}css/auto-complete.css" rel="stylesheet">
    {{ end }}
    ...
    </head>
    
  • ../layouts/partials/scripts.html

    Please note: as lunr.js is based on jquery, make sure jquery.js gets loaded 1st.

    </body>
    ...
    <!-- custom search -->
    {{ if not .Site.Params.disableSearch }}
        <script type="text/javascript" src="{{ .Site.BaseURL }}js/lunr.min.js"></script>
        <script type="text/javascript" src="{{ .Site.BaseURL }}js/auto-complete.js"></script>
                
        <script type="text/javascript">
            var baseurl = "{{ .Site.BaseURL }}";
        </script>
        <script type="text/javascript" src="{{ .Site.BaseURL }}js/search.js"></script>
    {{ end }}
    ...
     </body>
    
  • and finally, add a search entry box somewhere in your webpage layout:

    {{ if not .Site.Params.disableSearch }}
        <li class="dropdown">
        <a>
            <i class="fa fa-search"></i>
            <div class="searchbox pull-right">
            <input data-search-input id="search-by" type="text">
            </div>
        </a>
        </li>
    {{ end }}
    

That’s it.


comments powered by Disqus