mkdocs-material/docs/setup/setting-up-site-search.md

375 lines
12 KiB
Markdown
Raw Normal View History

2020-07-20 16:18:09 +03:00
---
template: overrides/main.html
---
# Setting up site search
2020-07-26 15:46:09 +03:00
Material for MkDocs provides an excellent, client-side search implementation,
2020-07-22 20:11:22 +03:00
omitting the need for the integration of third-party services, which might
2020-12-21 19:38:58 +03:00
be tricky to integrate to be compliant with data privacy regulations. Moreover,
with some effort, search can be made available [offline][1].
2020-07-20 16:18:09 +03:00
[1]: #offline-search
## Configuration
### Built-in search
[:octicons-file-code-24: Source][2] ·
2020-09-27 12:14:40 +03:00
[:octicons-cpu-24: Plugin][3]
2020-07-20 16:18:09 +03:00
The [built-in search plugin][3] integrates seamlessly with Material for MkDocs,
2020-10-11 13:20:36 +03:00
adding multilingual client-side search with [lunr][4] and [lunr-languages][5].
2020-07-20 16:18:09 +03:00
It's enabled by default, but must be re-added to `mkdocs.yml` when other plugins
are used:
``` yaml
plugins:
- search
```
The following options are supported:
2020-07-22 15:05:07 +03:00
`lang`{: #lang }
2020-07-20 16:18:09 +03:00
2020-07-21 17:01:22 +03:00
: :octicons-milestone-24: Default: _automatically set_ This option allows
2020-10-11 13:20:36 +03:00
to include the language-specific stemmers provided by [lunr-languages][5].
2020-07-20 16:18:09 +03:00
Note that Material for MkDocs will set this automatically based on the
2020-10-11 13:20:36 +03:00
[site language][6], but it may be overridden, e.g. to support multiple
2020-07-20 16:18:09 +03:00
languages:
=== "A single language"
``` yaml
plugins:
- search:
lang: ru
```
=== "Multiple languages"
``` yaml
plugins:
- search:
lang:
- en
- ru
```
The following languages are supported:
2020-12-21 19:38:58 +03:00
<div class="tx-columns" markdown="1">
- `ar` Arabic
- `da` Danish
- `du` Dutch
- `en` English
- `fi` Finnish
- `fr` French
- `de` German
- `hu` Hungarian
- `it` Italian
- `ja` Japanese
- `no` Norwegian
- `pt` Portuguese
- `ro` Romanian
- `ru` Russian
- `es` Spanish
- `sv` Swedish
- `th` Thai
- `tr` Turkish
- `vi` Vietnamese
</div>
2020-07-20 16:18:09 +03:00
2020-07-26 15:46:09 +03:00
_Material for MkDocs also tries to support languages that are not part of
this list by choosing the stemmer yielding the best result automatically_.
2020-07-20 16:18:09 +03:00
!!! warning "Only specify the languages you really need"
Be aware that including support for other languages increases the general
JavaScript payload by around 20kb (before `gzip`) and by another 15-30kb
per language.
2020-07-22 15:05:07 +03:00
`separator`{: #separator }
2020-07-20 16:18:09 +03:00
: :octicons-milestone-24: Default: _automatically set_ The separator for
2020-07-26 15:46:09 +03:00
indexing and query tokenization can be customized, making it possible to
index parts of words separated by other characters than whitespace and `-`,
e.g. by including `.`:
2020-07-20 16:18:09 +03:00
``` yaml
plugins:
- search:
separator: '[\s\-\.]+'
```
`prebuild_index`{: #prebuild-index }
2020-07-20 16:18:09 +03:00
: :octicons-milestone-24: Default: `false` · :octicons-beaker-24:
2020-10-11 13:20:36 +03:00
Experimental MkDocs can generate a [prebuilt index][7] of all pages during
2020-07-20 16:18:09 +03:00
build time, which provides performance improvements at the cost of more
bandwidth, as it reduces the build time of the search index:
``` yaml
plugins:
- search:
prebuild_index: true
```
This may be beneficial for large documentation projects served with
appropriate headers, i.e. `Content-Encoding: gzip`, but benchmarking before
deployment is recommended.
_Material for MkDocs doesn't provide official support for the other options of
this plugin, so they may be supported but can also yield weird results. Use
them at your own risk._
[2]: https://github.com/squidfunk/mkdocs-material/tree/master/src/assets/javascripts/integrations/search
[3]: https://www.mkdocs.org/user-guide/configuration/#search
2020-10-11 13:20:36 +03:00
[4]: https://lunrjs.com
[5]: https://github.com/MihaiValentin/lunr-languages
[6]: changing-the-language.md#site-language
[7]: https://www.mkdocs.org/user-guide/configuration/#prebuild_index
2020-07-20 16:18:09 +03:00
### Search suggestions
[:octicons-file-code-24: Source][8] ·
:octicons-unlock-24: Feature flag ·
:octicons-beaker-24: Experimental ·
[:octicons-heart-fill-24:{: .tx-heart } Insiders only][8]{: .tx-insiders }
When _search suggestions_ are enabled, the search will display the likeliest
completion for the last word, saving the user many key strokes by accepting the
2021-01-31 21:23:28 +03:00
suggestion with the ++arrow-right++ key.
2020-10-11 20:06:47 +03:00
2021-01-31 21:23:28 +03:00
Add the following lines to `mkdocs.yml`:
``` yaml
theme:
features:
- search.suggest
```
2020-12-21 19:38:58 +03:00
Searching for ^^code high^^ yields ^^code highlighting^^ as a suggestion:
2020-12-21 19:38:58 +03:00
<figure markdown="1">
[![Search suggestions][9]][9]
2020-12-21 19:38:58 +03:00
<figcaption markdown="1">
A demo is worth a thousand words — check it out at
[squidfunk.github.io/mkdocs-material-insiders][10]
2020-12-21 19:38:58 +03:00
</figcaption>
</figure>
[8]: ../insiders.md
[9]: ../assets/screenshots/search-suggestions.png
2020-12-21 19:38:58 +03:00
[10]: https://squidfunk.github.io/mkdocs-material-insiders/reference/code-blocks/?q=code+high
### Search highlighting
2020-10-11 13:20:36 +03:00
[:octicons-file-code-24: Source][8] ·
:octicons-unlock-24: Feature flag ·
:octicons-beaker-24: Experimental ·
2020-10-11 13:20:36 +03:00
[:octicons-heart-fill-24:{: .tx-heart } Insiders only][8]{: .tx-insiders }
When _search highlighting_ is enabled and a user clicks on a search result,
2020-08-02 23:09:44 +03:00
Material for MkDocs will highlight all occurrences after following the link.
2021-01-31 21:23:28 +03:00
Add the following lines to `mkdocs.yml`:
``` yaml
theme:
features:
- search.highlight
```
2020-12-21 19:38:58 +03:00
Searching for ^^code blocks^^ yields:
2020-12-21 19:38:58 +03:00
<figure markdown="1">
[![Search highlighting][11]][11]
2020-12-21 19:38:58 +03:00
<figcaption markdown="1">
A demo is worth a thousand words — check it out at
[squidfunk.github.io/mkdocs-material-insiders][12]
2020-12-21 19:38:58 +03:00
</figcaption>
</figure>
[11]: ../assets/screenshots/search-highlighting.png
[12]: https://squidfunk.github.io/mkdocs-material-insiders/reference/code-blocks/?h=code+blocks
2020-12-30 21:02:02 +03:00
### Search sharing
[:octicons-file-code-24: Source][8] ·
:octicons-unlock-24: Feature flag ·
:octicons-beaker-24: Experimental ·
[:octicons-heart-fill-24:{: .tx-heart } Insiders only][8]{: .tx-insiders }
When _search sharing_ is activated, a :material-share-variant: share button is
rendered next to the reset button, which allows to deep link to the current
2021-01-31 21:23:28 +03:00
search query and result. Add the following lines to `mkdocs.yml`:
2020-12-30 21:02:02 +03:00
``` yaml
theme:
features:
- search.share
```
When a user clicks the share button, the URL is automatically copied to the
clipboard.
<figure markdown="1">
[![Search sharing][13]][13]
<figcaption markdown="1">
A demo is worth a thousand words — check it out at
[squidfunk.github.io/mkdocs-material-insiders][14]
</figcaption>
</figure>
[13]: ../assets/screenshots/search-share.png
[14]: https://squidfunk.github.io/mkdocs-material-insiders/setup/setting-up-site-search/?q=share+search
2020-07-20 16:18:09 +03:00
### Offline search
2020-12-30 21:02:02 +03:00
[:octicons-file-code-24: Source][15] ·
[:octicons-cpu-24: Plugin][16] · :octicons-beaker-24: Experimental
2020-07-20 16:18:09 +03:00
If you distribute your documentation as `*.html` files, the built-in search
will not work out-of-the-box due to the restrictions modern browsers impose for
2020-12-30 21:02:02 +03:00
security reasons. This can be mitigated with the [localsearch][16] plugin in
combination with @squidfunk's [iframe-worker][17] polyfill.
2020-07-20 16:18:09 +03:00
2020-12-30 21:02:02 +03:00
For setup instructions, refer to the [official documentation][18].
2020-07-20 16:18:09 +03:00
2020-12-30 21:02:02 +03:00
[15]: https://github.com/squidfunk/mkdocs-material/blob/master/src/base.html
[16]: https://github.com/wilhelmer/mkdocs-localsearch/
[17]: https://github.com/squidfunk/iframe-worker
[18]: https://github.com/wilhelmer/mkdocs-localsearch#installation-material-v5
2020-07-20 16:18:09 +03:00
## Customization
The search implementation of Material for MkDocs is probably its most
sophisticated feature, as it tries to balance a _great typeahead experience_,
2020-07-26 15:46:09 +03:00
_good performance_, _accessibility_, and a result list that is _easy to scan_.
This is where Material for MkDocs deviates from other themes.
2020-07-20 16:18:09 +03:00
2020-07-26 15:46:09 +03:00
The following section explains how search can be customized to tailor it to
your needs.
2020-07-20 16:18:09 +03:00
### Query transformation
2020-12-30 21:02:02 +03:00
[:octicons-file-code-24: Source][19] ·
2020-07-21 17:01:22 +03:00
:octicons-mortar-board-24: Difficulty: _easy_
2020-07-20 16:18:09 +03:00
When a user enters a query into the search box, the query is pre-processed
before it is submitted to the search index. Material for MkDocs will apply the
2020-12-30 21:02:02 +03:00
following transformations, which can be customized by [extending the theme][20]:
2020-07-20 16:18:09 +03:00
``` ts
/**
* Default transformation function
*
* 1. Search for terms in quotation marks and prepend a `+` modifier to denote
* that the resulting document must contain all terms, converting the query
* to an `AND` query (as opposed to the default `OR` behavior). While users
* may expect terms enclosed in quotation marks to map to span queries, i.e.
* for which order is important, `lunr` doesn't support them, so the best
* we can do is to convert the terms to an `AND` query.
*
* 2. Replace control characters which are not located at the beginning of the
* query or preceded by white space, or are not followed by a non-whitespace
* character or are at the end of the query string. Furthermore, filter
* unmatched quotation marks.
*
* 3. Trim excess whitespace from left and right.
*
2020-08-02 23:09:44 +03:00
* @param query - Query value
2020-07-20 16:18:09 +03:00
*
* @return Transformed query value
*/
export function defaultTransform(query: string): string {
2020-08-02 23:09:44 +03:00
return query
2020-07-20 16:18:09 +03:00
.split(/"([^"]+)"/g) /* => 1 */
.map((terms, index) => index & 1
2020-07-20 16:18:09 +03:00
? terms.replace(/^\b|^(?![^\x00-\x7F]|$)|\s+/g, " +")
: terms
)
.join("")
.replace(/"|(?:^|\s+)[*+\-:^~]+(?=\s+|$)/g, "") /* => 2 */
.trim() /* => 3 */
}
```
If you want to switch to the default behavior of the `mkdocs` or `readthedocs`
template, both of which don't transform the query prior to submission, or
customize the `transform` function, you can do this by [overriding the
2020-12-30 21:02:02 +03:00
`config` block][21]:
2020-07-20 16:18:09 +03:00
``` html
2020-07-20 16:18:09 +03:00
{% block config %}
<script>
var search = {
transform: function(query) {
return query
}
}
</script>
{% endblock %}
```
The `transform` function will receive the query string as entered by the user
and must return the processed query string to be submitted to the search index.
2020-12-30 21:02:02 +03:00
[19]: https://github.com/squidfunk/mkdocs-material/blob/master/src/assets/javascripts/integrations/search/transform/index.ts
[20]: ../customization.md#extending-the-theme
[21]: ../customization.md#overriding-blocks
2020-07-20 16:18:09 +03:00
2020-07-22 12:57:41 +03:00
### Custom search
2020-07-20 16:18:09 +03:00
2020-12-30 21:02:02 +03:00
[:octicons-file-code-24: Source][22] ·
2020-07-21 17:01:22 +03:00
:octicons-mortar-board-24: Difficulty: _challenging_
2020-07-20 16:18:09 +03:00
2020-12-30 21:02:02 +03:00
Material for MkDocs implements search as part of a [web worker][23]. If you
2020-07-20 16:18:09 +03:00
want to switch the web worker with your own implementation, e.g. to submit
search to an external service, you can add a custom JavaScript file to the `docs`
2020-12-30 21:02:02 +03:00
directory and [override the `config` block][21]:
2020-07-20 16:18:09 +03:00
``` html
2020-07-20 16:18:09 +03:00
{% block config %}
<script>
var search = {
worker: "<url>"
}
</script>
{% endblock %}
```
Communication with the search worker is implemented using a standardized
message format using _discriminated unions_, i.e. through the `type` property
of the message. See the following interface definitions to learn about the
message formats:
2020-12-30 21:02:02 +03:00
- [:octicons-file-code-24: `SearchMessage`][24]
- [:octicons-file-code-24: `SearchIndex` and `SearchResult`][25]
2020-07-20 16:18:09 +03:00
The sequence and direction of messages is rather intuitive:
2020-11-16 00:25:11 +03:00
- :octicons-arrow-right-24: `SearchSetupMessage`
- :octicons-arrow-left-24: `SearchReadyMessage`
- :octicons-arrow-right-24: `SearchQueryMessage`
- :octicons-arrow-left-24: `SearchResultMessage`
2020-07-20 16:18:09 +03:00
2020-12-30 21:02:02 +03:00
[22]: https://github.com/squidfunk/mkdocs-material/blob/master/src/assets/javascripts/integrations/search/worker
[23]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers
[24]: https://github.com/squidfunk/mkdocs-material/blob/master/src/assets/javascripts/integrations/search/worker/message/index.ts
[25]: https://github.com/squidfunk/mkdocs-material/blob/master/src/assets/javascripts/integrations/search/_/index.ts