Guide to install the search module in single page mode.
Become a backer or sponsor to support our work.
Please make sure you have meet the requirements.
There is an example site and it’s source code to help you get started.
There also a guide for integrating Docsy with the search module.
hugo.yaml
1module:
2 imports:
3 - path: github.com/hugomods/search
hugo.toml
1[module]
2 [[module.imports]]
3 path = 'github.com/hugomods/search'
hugo.json
1{
2 "module": {
3 "imports": [
4 {
5 "path": "github.com/hugomods/search"
6 }
7 ]
8 }
9}
You should specify the lang
and dir
attributes on <html>
tag of base template (layouts/_default/baseof.html
by default), so that the module can recognize and render in current page language.
1<html
2 lang="{{ .Lang }}"
3 {{ with .Language.LanguageDirection }}dir="{{ . }}"{{ end }}>
4 <!-- ... -->
5</html>
The best practice is to include the search’s CSS and JS on the search page only when sharing the same base template.
1<html
2 lang="{{ .Lang }}"
3 {{ with .Language.LanguageDirection }}dir="{{ . }}"{{ end }}>
4 {{ if $isSearchPage }}
5 <!-- Search CSS -->
6 <!-- Search JS -->
7 {{ end }}
8</html>
But we couldn’t do that, since there isn’t a way to recognize whether the current page is a search page. See hugomods/search#76 and gohugoio/hugo#9368.
So we need a workaround, according to the Hugo look up order, we can achieve this by creating the baseof.search.html
template for single search page, see the demo site’s baseof.search.html.
There are multiple approaches to include the CSS.
Recommended when you’re using Hugo pipes to build CSS from source, it combines your styles and search styles into one bundle file, which is helpful to reduce the HTTP requests.
1{{/* NOTE: we must change the CSS target to separate the style between LTR and RTL sites. */}}
2{{/* Otherwise, Hugo may treats it as the same style (cached). */}}
3{{/* Ignore it if your themes and sites aren't going to support RTL. */}}
4{{ $rtl := eq .Language.LanguageDirection "rtl" }}
5{{ $cssTarget := cond $rtl "css/main.rtl.css" "css/main.css" }}
6{{ $css := resources.Get "main.scss" | toCSS }}
7{{/* If you have a prebuilt CSS, replace the $css with the following. */}}
8{{ $css := resources.Get "main.css" }}
9{{ $searchCSS := partial "search/assets/css-resource" . }}
10{{ $css = slice $searchCSS $css | resources.Concat $cssTarget }}
11<link rel="stylesheet" href="{{ $css.RelPermalink }}" />
main.scss
/main.css
is your styles file, which located in the assets
folder, replace it with yours.slice $searchCSS $css
puts the $css
after $searchCSS
, so that $css
style can override the search’s.search/assets/css-resource
is a partial that returns a search CSS resource.1@import "search/scss/index";
This way is more complex than the former, you’ll need to take care of the PostCSS, Autoprefixer and RTLCSS. See how CSS resource partial does.
This approach generates a <link>
tag.
1{{ partial "search/assets/css" . }}
We can achieve this via two ways.
Recommended when you’re using Hugo pipes to build JS from source, it combines your JS and search JS into one bundle file, which is helpful to reduce the HTTP requests.
1{{ $js := resources.Get "main.ts" | js.Build }}
2{{/* If you have a prebuilt JS file, use the following instead. */}}
3{{ $js := resources.Get "main.js" }}
4{{ $searchJS := partial "search/assets/js-resource" . }}
5{{ $js = slice $js $searchJS | resources.Concat "js/main.js" }}
6<script src="{{ $js.RelPermalink }}" defer></script>
Please note that you should not set the
async
attribute on thescript
.
main.ts
/main.js
is your JavaScript file, which located in the assets
folder, replace it with yours.search/assets/js-resource
is a partial that returns a search JS resource.This partial will generate a <script>
tag.
1{{ partial "search/assets/js" . }}
We’ll need to create a entrance for users, such as a link/menu to the search page, or a search form.
1{{ $searchURL := partial "search/functions/search-url" . }}
2
3{{/* Link to search page. */}}
4<a href="{{ $searchURL }}">Search</a>
5
6{{/* Search form. */}}
7<form action="{{ $searchURL }}">
8 <input type="search" name="q">
9</form>
The single search page accepts the following parameters from URL.
q
: query, the search input value.When you’re not familiar with the partials, you can simply add a menu with the /search
URL (related to the baseURL
).
Append the Search
and SearchIndex
formats into outputs.home
.
hugo.yaml
1outputs:
2 home:
3 - HTML
4 - RSS
5 - Search
6 - SearchIndex
hugo.toml
1[outputs]
2 home = ['HTML', 'RSS', 'Search', 'SearchIndex']
hugo.json
1{
2 "outputs": {
3 "home": [
4 "HTML",
5 "RSS",
6 "Search",
7 "SearchIndex"
8 ]
9 }
10}