1
0
mirror of https://github.com/squidfunk/mkdocs-material.git synced 2024-12-18 10:25:58 +01:00
mkdocs-material/docs/setup/setting-up-site-search.md
2021-10-10 12:19:14 +02:00

15 KiB
Raw Blame History

template search
overrides/main.html
boost
1.05

Setting up site search

Material for MkDocs provides an excellent, client-side search implementation, omitting the need for the integration of third-party services, which might be tricky to integrate to be compliant with data privacy regulations. Moreover, with some effort, search can be made available offline.

Configuration

!!! danger "Search: better, faster, smaller"

We rebuilt the search plugin and integration from the ground up, introducing [rich search previews](../blog/2021/search-better-faster-smaller.md#rich-search-previews), much better [tokenizer support](../blog/2021/search-better-faster-smaller.md#tokenizer-lookahead), [more accurate highlighting](../blog/2021/search-better-faster-smaller.md#accurate-highlighting) and much more. Read the [blog article](../blog/2021/search-better-faster-smaller.md) to learn more about our new search implementation. Start using it immediately by [becoming a sponsor][20]!

:octicons-file-code-24: Source · :octicons-cpu-24: Plugin · :octicons-heart-fill-24:{ .mdx-heart } Better in Insiders{ .mdx-insiders }

The built-in search plugin integrates seamlessly with Material for MkDocs, adding multilingual client-side search with lunr and lunr-languages. It's enabled by default, but must be re-added to mkdocs.yml when other plugins are used:

plugins:
  - search

The following options are supported:

lang{ #lang }

:octicons-milestone-24: Default: automatically set This option allows to include the language-specific stemmers provided by lunr-languages. Note that Material for MkDocs will set this automatically based on the site language, but it may be overridden, e.g. to support multiple languages:

=== "A single language"

``` yaml
plugins:
  - search:
      lang: ru
```

=== "Multiple languages"

``` yaml
plugins:
  - search:
      lang:
        - en
        - ru
```

The following languages are supported:

  • 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

Material for MkDocs also tries to support languages that are not part of this list by choosing the stemmer yielding the best result automatically.

!!! 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.
separator{ #separator }

:octicons-milestone-24: Default: automatically set The separator for 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 .:

plugins:
  - search:
      separator: '[\s\-\.]+'
prebuild_index{ #prebuild-index }1

:octicons-milestone-24: Default: false · :octicons-archive-24: Deprecated MkDocs can generate a prebuilt index of all pages during build time, which provides performance improvements at the cost of more bandwidth, as it reduces the build time of the search index:

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.

The prebuild_index feature was deprecated in 7.3.0 and will be removed in 8.x. Insiders removed support in 3.0.0 with the advent of the new search plugin.

Material for MkDocs doesn't provide official support for the other options of this plugin, so they may be supported but might yield unexpected results. Use them at your own risk.

Search suggestions

:octicons-unlock-24: Feature flag · :octicons-beaker-24: Experimental · :octicons-tag-24: 7.2.0 ... present

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 suggestion with the ++arrow-right++ key.

Add the following lines to mkdocs.yml:

theme:
  features:
    - search.suggest

Searching for :octicons-search-24: search su yields ^^search suggestions^^ as a suggestion:

Search suggestions

Search highlighting

:octicons-unlock-24: Feature flag · :octicons-beaker-24: Experimental · :octicons-tag-24: 7.2.0 ... present

When search highlighting is enabled and a user clicks on a search result, Material for MkDocs will highlight all occurrences after following the link. Add the following lines to mkdocs.yml:

theme:
  features:
    - search.highlight

Searching for :octicons-search-24: code blocks yields:

Search highlighting

Search sharing

:octicons-unlock-24: Feature flag · :octicons-beaker-24: Experimental · :octicons-tag-24: 7.2.0 ... present

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 search query and result. Add the following lines to mkdocs.yml:

theme:
  features:
    - search.share

When a user clicks the share button, the URL is automatically copied to the clipboard.

Search sharing

:octicons-file-code-24: Source · :octicons-cpu-24: Plugin

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 security reasons. This can be mitigated with the localsearch plugin in combination with @squidfunk's iframe-worker polyfill.

For setup instructions, refer to the official documentation.

!!! tip

When distributing documentation as HTML files to be opened from the file
system, you will also want to set `use_directory_urls: false` in
`mkdocs.yml` to make page links function correctly.

Usage

Search boosting

:octicons-heart-fill-24:{ .mdx-heart } Insiders{ .mdx-insiders } · :octicons-note-24: Metadata · :octicons-tag-24: insiders-2.8.0 ... present

In order to give specific pages a higher relevance in search, lunr supports page-specific boosts, which can be defined for each page by leveraging the Metadata extension:

---
search:
  boost: 100
---

# Document title
...

Search exclusion

:octicons-heart-fill-24:{ .mdx-heart } Insiders{ .mdx-insiders } · :octicons-note-24: Metadata · :octicons-beaker-24: Experimental · :octicons-tag-24: insiders-3.1.0 ... present

Excluding pages

Sometimes, it's necessary to exclude a page from the search index, which can be achieved by adding the following front matter using the Metadata extension:

---
search:
  exclude: true
---

# Document title
...

Excluding sections

With the help of the Attribute List extension, it's possible to exclude a specific section of a page from search by adding the { data-search-exclude } pragma after the Markdown heading:

=== "docs/page.md"

``` markdown
# Document title

## Section 1

The content of this section is included

## Section 2 { data-search-exclude }

The content of this section is excluded
```

=== "search_index.json"

``` json
{
  ...
  "docs": [
    {
      "location":"page/",
      "text":"",
      "title":"Document title"
    },
    {
      "location":"page/#section-1",
      "text":"<p>The content of this section is included</p>",
      "title":"Section 1"
    }
  ]
}
```

Excluding blocks

If even more fine-grained control is needed, content blocks can be excluded from search sections with a { data-search-exclude } pragma, so they will not be included in the search index:

=== "docs/page.md"

``` markdown
# Document title

The content of this block is included

The content of this block is excluded
{ data-search-exclude }
```

=== "search_index.json"

``` json
{
  ...
  "docs": [
    {
      "location":"page/",
      "text":"<p>The content of this block is included</p>",
      "title":"Document title"
    }
  ]
}
```

Customization

The search implementation of Material for MkDocs is probably its most sophisticated feature, as it tries to balance a great typeahead experience, good performance, accessibility, and a result list that is easy to scan. This is where Material for MkDocs deviates from other themes.

The following section explains how search can be customized to tailor it to your needs.

Query transformation

:octicons-file-code-24: Source · :octicons-mortar-board-24: Difficulty: easy

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 following transformations, which can be customized by extending the theme:

export function defaultTransform(query: string): string {
  return query
    .split(/"([^"]+)"/g) /* (1) */
      .map((terms, index) => index & 1
        ? terms.replace(/^\b|^(?![^\x00-\x7F]|$)|\s+/g, " +")
        : terms
      )
      .join("")
    .replace(/"|(?:^|\s+)[*+\-:^~]+(?=\s+|$)/g, "") /* (2) */
    .trim() /* (3) */
}
  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.

If you want to switch to the default behavior of the mkdocs and readthedocs themes, both of which don't transform the query prior to submission, or customize the transform function, you can do this by overriding the config block:

{% extends "base.html" %}

{% block config %}
  {{ super() }}
  <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.

:octicons-file-code-24: Source · :octicons-mortar-board-24: Difficulty: challenging

Material for MkDocs implements search as part of a web worker. If you 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 directory and override the config block:

{% block config %}
  {{ super() }}
  <script>
    var __search = {
      worker: "<url>"
    }
  </script>
{% endblock %}

Communication with the search worker is implemented using a designated 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:

The sequence and direction of messages is rather intuitive:

  • :octicons-arrow-right-24: SearchSetupMessage

  • :octicons-arrow-left-24: SearchReadyMessage

  • :octicons-arrow-right-24: SearchQueryMessage

  • :octicons-arrow-left-24: SearchResultMessage