This blog is powered by Jekyll, a static site generator. There is no database, nothing to search against, the site is simply composed of a few HTML pages referencing each other. Being search experts, we can leverage Coveo to add powerful search to Jekyll.
Indexing the content
Since we are dealing with a structured site containing static HTML pages, our Web Pages Connector will get the job done.
In addition to creating a new Web Pages Connector source to index the blog, we created a custom field to have facetted tags on the search result page.
“Installing” the Coveo JavaScript Search Framework in Jekyll
The JavaScript Search Framework is simply a zip file containing image, css and JavaScript files. For this straightforward integration, we added the following files to the Jekyll folder structure:
css/CoveoFullSearch.css
js/CoveoJsSearch.WithDependencies.min.js
js/d3.min.js
images/sprites.png
images/wait.gif
images/wait_circle_small.gif
images/wait_facet.gif
images/wait_facet_search.gif
Adding the search page
Each Jekyll page is rendered using a layout, we have two:
base
post
We created a new page at the root of the site: search.html
This page is using the base layout, just like the home page, and contains the following:
The code above results in a simple search page with two facets:
Author (out of the box, no custom field is needed)
Tags (based on the tags custom field we created earlier)
Searching from anywhere on the blog
We wanted to have a search box on every page. We proceeded to change our two layout files to include the following HTML element in the header:
For the search box and the search page to work, the JavaScript Search Framework resources must be included in all the pages of the blog. These two lines were also added to the base and post layouts:
As you can see, we created the _search.html file in the _includesJekyll folder to centralize the JavaScript dependencies, here is what it contains:
Externalizing the search box
With the Search Endpoint configured in our _search.html file, the search page was already working. However, we had two problems:
the search interface was initiated two times
the search box was only working on the search page itself
To avoid the double init problem, we added logic to prevent the standalone search box from initializing in the search page. If we are not on the search page, we initialize the search box directly and give it the path of our search page, i.e. /search:
If however we are on the search page, we pass the mySearchBox variable as an externalComponents to the search page:
You can learn more about the Standalone Search Box possibilities in our documentation.