> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Highlighting in InstantSearch.js

> How to use highlighting and snippeting in InstantSearch.js to demonstrate to searchers why a result matches a query.

export const Records = () => <Tooltip tip="A record is a searchable object in an Algolia index. Each record consists of named attributes." cta="Algolia records" href="/doc/guides/sending-and-managing-data/prepare-your-data#algolia-records">
    records
  </Tooltip>;

## Highlighting

Highlighting is a vital tool for showing searchers why a result matched their query by providing different styling to all matched query words.

By default, Highlighting is enabled on all [`searchableAttributes`](/doc/api-reference/api-parameters/searchableAttributes)
unless specified otherwise in [`attributesToHighlight`](/doc/api-reference/api-parameters/attributesToHighlight).

<Note>
  Use one of the API clients or the Algolia dashboard, not InstantSearch, to configure

  `attributesToHighlight`.
</Note>

Below is an example of how to configure which attributes to highlight:

<CodeGroup>
  ```cs C# theme={"system"}
  var response = await client.SetSettingsAsync(
    "INDEX_NAME",
    new IndexSettings
    {
      AttributesToHighlight = new List<string> { "author", "title", "content" },
    }
  );
  ```

  ```dart Dart theme={"system"}
  final response = await client.setSettings(
    indexName: "INDEX_NAME",
    indexSettings: IndexSettings(
      attributesToHighlight: [
        "author",
        "title",
        "content",
      ],
    ),
  );
  ```

  ```go Go theme={"system"}
  response, err := client.SetSettings(client.NewApiSetSettingsRequest(
    "INDEX_NAME",
    search.NewEmptyIndexSettings().SetAttributesToHighlight(
      []string{"author", "title", "content"})))
  if err != nil {
    // handle the eventual error
    panic(err)
  }
  ```

  ```java Java theme={"system"}
  UpdatedAtResponse response = client.setSettings(
    "INDEX_NAME",
    new IndexSettings().setAttributesToHighlight(Arrays.asList("author", "title", "content"))
  );
  ```

  ```js JavaScript theme={"system"}
  const response = await client.setSettings({
    indexName: 'theIndexName',
    indexSettings: { attributesToHighlight: ['author', 'title', 'content'] },
  });
  ```

  ```kotlin Kotlin theme={"system"}
  var response =
    client.setSettings(
      indexName = "INDEX_NAME",
      indexSettings = IndexSettings(attributesToHighlight = listOf("author", "title", "content")),
    )
  ```

  ```php PHP theme={"system"}
  $response = $client->setSettings(
      'INDEX_NAME',
      ['attributesToHighlight' => [
          'author',

          'title',

          'content',
      ],
      ],
  );
  ```

  ```python Python theme={"system"}
  response = client.set_settings(
      index_name="INDEX_NAME",
      index_settings={
          "attributesToHighlight": [
              "author",
              "title",
              "content",
          ],
      },
  )
  ```

  ```ruby Ruby theme={"system"}
  response = client.set_settings(
    "INDEX_NAME",
    Algolia::Search::IndexSettings.new(attributes_to_highlight: ["author", "title", "content"])
  )
  ```

  ```scala Scala theme={"system"}
  val response = Await.result(
    client.setSettings(
      indexName = "INDEX_NAME",
      indexSettings = IndexSettings(
        attributesToHighlight = Some(Seq("author", "title", "content"))
      )
    ),
    Duration(100, "sec")
  )
  ```

  ```swift Swift theme={"system"}
  let response = try await client.setSettings(
      indexName: "INDEX_NAME",
      indexSettings: IndexSettings(attributesToHighlight: ["author", "title", "content"])
  )
  ```
</CodeGroup>

**If `exactOnSingleWordQuery` is set to `word`, only exact matches will be highlighted: partial matches and prefixes won't be.**

### Response information

The response includes a [`_highlightResult`](/doc/rest-api/search/search-single-index#response-hits-items-highlight-result) for each attribute, containing:

* The attribute's value with highlighting
* The match level (how many query words matched)
* A boolean indicating if the whole attribute is highlighted
* The matched words for each attribute.

For example:

```json JSON icon=braces theme={"system"}
{
  "value": "<em>Action</em>tec - 4-Port Ethernet Broadband Router with Wireless-N - Black",
  "matchLevel": "full",
  "fullyHighlighted": false,
  "matchedWords": ["action"]
}
```

#### Performance

Algolia highlights the first 50,000 characters of the whole result set (5,000 logograms for CJK languages). This limit prevents impacting the user experience by ensuring a fast response time even with large results.

#### Sanitize the results

Since Algolia returns highlighted results as they're stored in the engine, make sure you sanitize your HTML.
**Unsanitized or invalid HTML content, particularly with user-provided content, can be a security risk** and opens up the possibility of [cross-site-scripting attacks](https://en.wikipedia.org/wiki/Cross-site_scripting) on your site.

### Pre- and post-tags

The primary configurations that you can set for highlighting are pre-tags and post-tags.
This configuration lets you use any tag (HTML or otherwise) to highlight results in the UI.

You can set the pre-tags and post-tags (that is, the strings before and after the matched query words) to any string value. They're set to `<em>` and `</em>` by default.

You can configure this setting using the [`highlightPreTag`](/doc/api-reference/api-parameters/highlightPreTag) and [`highlightPostTag`](/doc/api-reference/api-parameters/highlightPostTag) parameters at either query or indexing time.

<CodeGroup>
  ```cs C# theme={"system"}
  var response = await client.SetSettingsAsync(
    "INDEX_NAME",
    new IndexSettings
    {
      AttributesToHighlight = new List<string> { "author", "title", "content" },
      HighlightPreTag = "<em class=\"search-highlight\">",
      HighlightPostTag = "</em>",
    }
  );
  ```

  ```dart Dart theme={"system"}
  final response = await client.setSettings(
    indexName: "INDEX_NAME",
    indexSettings: IndexSettings(
      attributesToHighlight: [
        "author",
        "title",
        "content",
      ],
      highlightPreTag: "<em class=\"search-highlight\">",
      highlightPostTag: "</em>",
    ),
  );
  ```

  ```go Go theme={"system"}
  response, err := client.SetSettings(client.NewApiSetSettingsRequest(
    "INDEX_NAME",
    search.NewEmptyIndexSettings().SetAttributesToHighlight(
      []string{"author", "title", "content"}).SetHighlightPreTag("<em class=\"search-highlight\">").SetHighlightPostTag("</em>")))
  if err != nil {
    // handle the eventual error
    panic(err)
  }
  ```

  ```java Java theme={"system"}
  UpdatedAtResponse response = client.setSettings(
    "INDEX_NAME",
    new IndexSettings()
      .setAttributesToHighlight(Arrays.asList("author", "title", "content"))
      .setHighlightPreTag("<em class=\"search-highlight\">")
      .setHighlightPostTag("</em>")
  );
  ```

  ```js JavaScript theme={"system"}
  const response = await client.setSettings({
    indexName: 'theIndexName',
    indexSettings: {
      attributesToHighlight: ['author', 'title', 'content'],
      highlightPreTag: '<em class="search-highlight">',
      highlightPostTag: '</em>',
    },
  });
  ```

  ```kotlin Kotlin theme={"system"}
  var response =
    client.setSettings(
      indexName = "INDEX_NAME",
      indexSettings =
        IndexSettings(
          attributesToHighlight = listOf("author", "title", "content"),
          highlightPreTag = "<em class=\"search-highlight\">",
          highlightPostTag = "</em>",
        ),
    )
  ```

  ```php PHP theme={"system"}
  $response = $client->setSettings(
      'INDEX_NAME',
      ['attributesToHighlight' => [
          'author',

          'title',

          'content',
      ],
          'highlightPreTag' => '<em class="search-highlight">',
          'highlightPostTag' => '</em>',
      ],
  );
  ```

  ```python Python theme={"system"}
  response = client.set_settings(
      index_name="INDEX_NAME",
      index_settings={
          "attributesToHighlight": [
              "author",
              "title",
              "content",
          ],
          "highlightPreTag": '<em class="search-highlight">',
          "highlightPostTag": "</em>",
      },
  )
  ```

  ```ruby Ruby theme={"system"}
  response = client.set_settings(
    "INDEX_NAME",
    Algolia::Search::IndexSettings.new(
      attributes_to_highlight: ["author", "title", "content"],
      highlight_pre_tag: "<em class=\"search-highlight\">",
      highlight_post_tag: "</em>"
    )
  )
  ```

  ```scala Scala theme={"system"}
  val response = Await.result(
    client.setSettings(
      indexName = "INDEX_NAME",
      indexSettings = IndexSettings(
        attributesToHighlight = Some(Seq("author", "title", "content")),
        highlightPreTag = Some("<em class=\"search-highlight\">"),
        highlightPostTag = Some("</em>")
      )
    ),
    Duration(100, "sec")
  )
  ```

  ```swift Swift theme={"system"}
  let response = try await client.setSettings(
      indexName: "INDEX_NAME",
      indexSettings: IndexSettings(
          attributesToHighlight: ["author", "title", "content"],
          highlightPreTag: "<em class=\"search-highlight\">",
          highlightPostTag: "</em>"
      )
  )
  ```
</CodeGroup>

**Pre-tag and post-tag settings are typically used together.**

### Highlighting using InstantSearch

Algolia provides a `Highlight` widget in the InstantSearch libraries to highlight matches on the frontend.
Refer to the [widget docs](/doc/api-reference/widgets/highlight/js) for usage notes and code examples.

## Snippeting

Snippeting returns parts of the matched attribute, namely, the matched words and some words around them. Unlike highlighting, you must enable snippeting for each attribute you wish to snippet, although you can set the value `*` to snippet all attributes.

{/* vale Vale.Spelling = NO */}

The snippeted result wraps the matched words in the pre-highlighting and post-highlighting tags.

<Note>
  Use one of the API clients or the Algolia dashboard, not InstantSearch, to configure

  `attributesToSnippet`.
</Note>

An example configuration of the [`attributesToSnippet`](/doc/api-reference/api-parameters/attributesToSnippet):

<CodeGroup>
  ```cs C# theme={"system"}
  var response = await client.SetSettingsAsync(
    "INDEX_NAME",
    new IndexSettings
    {
      AttributesToSnippet = new List<string> { "content:80", "description" },
    }
  );
  ```

  ```dart Dart theme={"system"}
  final response = await client.setSettings(
    indexName: "INDEX_NAME",
    indexSettings: IndexSettings(
      attributesToSnippet: [
        "content:80",
        "description",
      ],
    ),
  );
  ```

  ```go Go theme={"system"}
  response, err := client.SetSettings(client.NewApiSetSettingsRequest(
    "INDEX_NAME",
    search.NewEmptyIndexSettings().SetAttributesToSnippet(
      []string{"content:80", "description"})))
  if err != nil {
    // handle the eventual error
    panic(err)
  }
  ```

  ```java Java theme={"system"}
  UpdatedAtResponse response = client.setSettings(
    "INDEX_NAME",
    new IndexSettings().setAttributesToSnippet(Arrays.asList("content:80", "description"))
  );
  ```

  ```js JavaScript theme={"system"}
  const response = await client.setSettings({
    indexName: 'theIndexName',
    indexSettings: { attributesToSnippet: ['content:80', 'description'] },
  });
  ```

  ```kotlin Kotlin theme={"system"}
  var response =
    client.setSettings(
      indexName = "INDEX_NAME",
      indexSettings = IndexSettings(attributesToSnippet = listOf("content:80", "description")),
    )
  ```

  ```php PHP theme={"system"}
  $response = $client->setSettings(
      'INDEX_NAME',
      ['attributesToSnippet' => [
          'content:80',

          'description',
      ],
      ],
  );
  ```

  ```python Python theme={"system"}
  response = client.set_settings(
      index_name="INDEX_NAME",
      index_settings={
          "attributesToSnippet": [
              "content:80",
              "description",
          ],
      },
  )
  ```

  ```ruby Ruby theme={"system"}
  response = client.set_settings(
    "INDEX_NAME",
    Algolia::Search::IndexSettings.new(attributes_to_snippet: ["content:80", "description"])
  )
  ```

  ```scala Scala theme={"system"}
  val response = Await.result(
    client.setSettings(
      indexName = "INDEX_NAME",
      indexSettings = IndexSettings(
        attributesToSnippet = Some(Seq("content:80", "description"))
      )
    ),
    Duration(100, "sec")
  )
  ```

  ```swift Swift theme={"system"}
  let response = try await client.setSettings(
      indexName: "INDEX_NAME",
      indexSettings: IndexSettings(attributesToSnippet: ["content:80", "description"])
  )
  ```
</CodeGroup>

For each attribute, you can configure how snippet results are displayed by defining:

* The number of words in the resulting snippet (`nbWords`)
* The text used to replace removed words in the snippet (`snippetEllipsisText`).

### Number of words

You can set the number of words to return when defining your [`attributesToSnippet`](/doc/api-reference/api-parameters/attributesToSnippet) with the syntax `attribute:nbWords`. For example, `body:20` returns twenty-word snippets for the attribute `body`. When undefined, the value defaults to 10.

<CodeGroup>
  ```cs C# theme={"system"}
  var response = await client.SetSettingsAsync(
    "INDEX_NAME",
    new IndexSettings
    {
      AttributesToSnippet = new List<string> { "body:20", "title" },
    }
  );
  ```

  ```dart Dart theme={"system"}
  final response = await client.setSettings(
    indexName: "INDEX_NAME",
    indexSettings: IndexSettings(
      attributesToSnippet: [
        "body:20",
        "title",
      ],
    ),
  );
  ```

  ```go Go theme={"system"}
  response, err := client.SetSettings(client.NewApiSetSettingsRequest(
    "INDEX_NAME",
    search.NewEmptyIndexSettings().SetAttributesToSnippet(
      []string{"body:20", "title"})))
  if err != nil {
    // handle the eventual error
    panic(err)
  }
  ```

  ```java Java theme={"system"}
  UpdatedAtResponse response = client.setSettings(
    "INDEX_NAME",
    new IndexSettings().setAttributesToSnippet(Arrays.asList("body:20", "title"))
  );
  ```

  ```js JavaScript theme={"system"}
  const response = await client.setSettings({
    indexName: 'theIndexName',
    indexSettings: { attributesToSnippet: ['body:20', 'title'] },
  });
  ```

  ```kotlin Kotlin theme={"system"}
  var response =
    client.setSettings(
      indexName = "INDEX_NAME",
      indexSettings = IndexSettings(attributesToSnippet = listOf("body:20", "title")),
    )
  ```

  ```php PHP theme={"system"}
  $response = $client->setSettings(
      'INDEX_NAME',
      ['attributesToSnippet' => [
          'body:20',

          'title',
      ],
      ],
  );
  ```

  ```python Python theme={"system"}
  response = client.set_settings(
      index_name="INDEX_NAME",
      index_settings={
          "attributesToSnippet": [
              "body:20",
              "title",
          ],
      },
  )
  ```

  ```ruby Ruby theme={"system"}
  response = client.set_settings(
    "INDEX_NAME",
    Algolia::Search::IndexSettings.new(attributes_to_snippet: ["body:20", "title"])
  )
  ```

  ```scala Scala theme={"system"}
  val response = Await.result(
    client.setSettings(
      indexName = "INDEX_NAME",
      indexSettings = IndexSettings(
        attributesToSnippet = Some(Seq("body:20", "title"))
      )
    ),
    Duration(100, "sec")
  )
  ```

  ```swift Swift theme={"system"}
  let response = try await client.setSettings(
      indexName: "INDEX_NAME",
      indexSettings: IndexSettings(attributesToSnippet: ["body:20", "title"])
  )
  ```
</CodeGroup>

With `nbWords` set to 6:

```txt theme={"system"}
"As Gregor Samsa awoke one morning …"
```

And `nbWords` set to 10:

```txt theme={"system"}
"As Gregor Samsa awoke one morning from uneasy dreams he …"
```

### Ellipsis text

The engine inserts text to show where words have been removed from the snippeted text.

The default replacement text is `…` (Unicode `U+20216`): an ellipsis character. However, you can change this with the [`snippetEllipsisText`](/doc/api-reference/api-parameters/snippetEllipsisText) setting:

<CodeGroup>
  ```cs C# theme={"system"}
  var response = await client.SetSettingsAsync(
    "INDEX_NAME",
    new IndexSettings { SnippetEllipsisText = "[&hellip;]" }
  );
  ```

  ```dart Dart theme={"system"}
  final response = await client.setSettings(
    indexName: "INDEX_NAME",
    indexSettings: IndexSettings(
      snippetEllipsisText: "[&hellip;]",
    ),
  );
  ```

  ```go Go theme={"system"}
  response, err := client.SetSettings(client.NewApiSetSettingsRequest(
    "INDEX_NAME",
    search.NewEmptyIndexSettings().SetSnippetEllipsisText("[&hellip;]")))
  if err != nil {
    // handle the eventual error
    panic(err)
  }
  ```

  ```java Java theme={"system"}
  UpdatedAtResponse response = client.setSettings("INDEX_NAME", new IndexSettings().setSnippetEllipsisText("[&hellip;]"));
  ```

  ```js JavaScript theme={"system"}
  const response = await client.setSettings({
    indexName: 'theIndexName',
    indexSettings: { snippetEllipsisText: '[&hellip;]' },
  });
  ```

  ```kotlin Kotlin theme={"system"}
  var response =
    client.setSettings(
      indexName = "INDEX_NAME",
      indexSettings = IndexSettings(snippetEllipsisText = "[&hellip;]"),
    )
  ```

  ```php PHP theme={"system"}
  $response = $client->setSettings(
      'INDEX_NAME',
      ['snippetEllipsisText' => '[&hellip;]',
      ],
  );
  ```

  ```python Python theme={"system"}
  response = client.set_settings(
      index_name="INDEX_NAME",
      index_settings={
          "snippetEllipsisText": "[&hellip;]",
      },
  )
  ```

  ```ruby Ruby theme={"system"}
  response = client.set_settings(
    "INDEX_NAME",
    Algolia::Search::IndexSettings.new(snippet_ellipsis_text: "[&hellip;]")
  )
  ```

  ```scala Scala theme={"system"}
  val response = Await.result(
    client.setSettings(
      indexName = "INDEX_NAME",
      indexSettings = IndexSettings(
        snippetEllipsisText = Some("[&hellip;]")
      )
    ),
    Duration(100, "sec")
  )
  ```

  ```swift Swift theme={"system"}
  let response = try await client.setSettings(
      indexName: "INDEX_NAME",
      indexSettings: IndexSettings(snippetEllipsisText: "[&hellip;]")
  )
  ```
</CodeGroup>

The engine adds an extra space (Unicode `U+0020`) before and after `snippetEllipsisText`. For example:

```txt theme={"system"}
"… awoke one morning … "
```

### Sanitize the results

Algolia removes all HTML tags from the snippeted results to ensure the text displays correctly within pre-highlighting and post-highlighting tags.

#### An alternative to snippets

If you want an attribute to keep its HTML formatting,
instead of asking Algolia to shorten (snippet) it for you,
create short-form <Records /> in your data based on a subset of the original,
longer-form records.
Ensure that these short-form records are restricted to an appropriate length and contain valid HTML (all opening tags have matching closing tags).
You can do this programmatically,
for example, with:

* RegExp. If you have a limited, known set of HTML, you can use regular expressions to split the content. Be aware of the [limitations of the RegExp approach](https://blog.codinghorror.com/parsing-html-the-cthulhu-way/).
* HTML splitter code

### Snippeting using InstantSearch

There's a `Snippet` widget in the InstantSearch libraries to snippet text attributes on the frontend.
Refer to the [widget docs](/doc/api-reference/widgets/snippet/js) for usage notes and code examples.
