Contents

Add Lunr Search to Hugo site

What’s covered in this post?

Hugo ships with out search, yet I love it. However, I’ve managed to integrate lunr search that is supported by the theme Loveit I’m using on this website. With that being said, this post will cover how I integrate lurn on my website - for demo, go ahead and search for something on this website :)

Install or update!

Make sure you update or install before we start.

Today, there are handfull of search tools available for Hugo websites. One popular option is Hugo-lunr, which utilizes Lunr search. It’s easily installed via npm. For more information, visit its npm page: hugo-lunr .

1. Edit package.json

Lets start!

Go to package.json in project root directory and add the following

1
2
3
	"scripts": {
    "index": "hugo-lunr -i \"content/subdir/**\" -o static/lunr.json"
  }

here is my package.json for quick reference

Info
Line 2 will allow you to change the output of the index file generation. You can change the path as you need.

2. Edit config.toml

Make sure you enable search in your config.toml - if don’t exist, go ahead and add at the end of the page.

1
2
3
4
5
# Search config
  [params.search]
    enable = true
    # type of search engine ["lunr", "algolia"]
    type = "lunr"

and then add out-puts if not added already (must go into config.toml thats in root directory of the your project)

1
2
3
[outputs]
  home = ["HTML", "RSS", "JSON"]
  page = ["HTML"]

STOP
make sure you add outputs to the config.toml file that exist at the root of your project.
you can check my both config.toml file here

3. Build the index

After step 1 and 2 you shall be able to build the site index. Go ahead and open the terminal and run the following command from your project root directory.

1
npm run index 

once you run this command, you will see the file lunr.json generated in static folder at the root of your project directory.

Now build your website.

1
hugo

This will copy the lunr.json from static dir to the public dir of your project.

4. Edit baseof.html

Open themes/<theme-name>/layouts/_default/baseof.html(this path might be diff in your case, based on your theme) and add the following line before closing the head

1
<script src="https://cdnjs.cloudflare.com/ajax/libs/lunr.js/2.3.9/lunr.min.js"></script>

and at the end of the page, add the following script. this will fetch the data from lurn.json file that’s generated in step 3

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<!-- Script to load Lunr index and handle search -->
<script>
    document.addEventListener('DOMContentLoaded', function() {
        var searchIndex;

        fetch('/lunr.json')
            .then(response => response.json())
            .then(data => {
                searchIndex = lunr(function () {
                    this.field('title');
                    this.field('content');
                    this.field('tags');
                    this.ref('uri');

                    data.forEach(doc => {
                        this.add(doc);
                    });
                });
            });

        function performSearch(query) {
            if (searchIndex) {
                var results = searchIndex.search(query);
                displayResults(results);
            }
        }

        function displayResults(results) {
            var resultsContainer = document.getElementById('search-results');
            resultsContainer.innerHTML = '';
            results.forEach(result => {
                var item = document.createElement('div');
                item.innerHTML = `<a href="${result.ref}">${result.ref}</a>`;
                resultsContainer.appendChild(item);
            });
        }

        var searchInputDesktop = document.getElementById('search-input-desktop');
        if (searchInputDesktop) {
            searchInputDesktop.addEventListener('input', function() {
                performSearch(searchInputDesktop.value);
            });
        }

        var searchInputMobile = document.getElementById('search-input-mobile');
        if (searchInputMobile) {
            searchInputMobile.addEventListener('input', function() {
                performSearch(searchInputMobile.value);
            });
        }
    });
</script>
STOP
Code generated in this step 4 is by ChatGPT. It is advised to thoroughly check before using it yourself.

By following the above steps, you have successfully setup lunr on your webpage. You shall be able to search your website.

  1. run the following to build the index npm run index
  2. run hugo to build the website
  3. start your server with hugo server -D

Now start your hugo server using the cmd hugo server -D and you shall be able to search your through your content.

https://i.pinimg.com/736x/90/71/7f/90717fc83380e01fbc6124973aa84217.jpg

TIP
It is worth mentioning that every time you create a new post or updated an existing one, make sure perform step 3 (build index) to index the updated content for the search.

Conclusion

I don’t claim expertise in Hugo or Lunr. I integrated Lunr by researching various resources and credit those who explained it before me. I only take credit for detailing how I implemented Lunr search on my website. If you have any questions or suggestions, please post them here .