> ## Documentation Index
> Fetch the complete documentation index at: https://nikita-shkoda.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Highlighting

> Emphasize matched query terms via affix snippets or fully highlighted fields. Options, compiler mapping, and result helpers.

When you want to emphasize matched query terms, use highlighting. It supports concise affix snippets around matches or fully highlighted fields.

## DSL usage

Verbatim ticket example:

```ruby theme={null}
rel = SearchEngine::Book
  .highlight(fields: %i[name description], full_fields: %i[description], start_tag: "<em>", end_tag: "</em>", affix_tokens: 8, snippet_threshold: 30)
```

Variations:

```ruby theme={null}
# Use <mark> tags and only snippet fields
SearchEngine::Book.highlight(fields: %i[name], start_tag: "<mark>", end_tag: "</mark>")

# Only full_fields (no affix snippets)
SearchEngine::Book.highlight(fields: %i[name], full_fields: %i[description])
```

## Compiler mapping

```mermaid theme={null}
flowchart LR
  A[Relation.highlight opts] --> B[Normalize (HighlightPlan)]
  B --> C[Params: highlight_* + snippet_threshold]
  C --> D[Search request]
  D --> E[Response: highlights per hit]
  E --> F[Hit decorators: highlights & snippet_for]
```

Emitted Typesense params:

* <code>highlight\_fields</code>
* <code>highlight\_full\_fields</code>
* <code>highlight\_affix\_num\_tokens</code>
* <code>highlight\_start\_tag</code>
* <code>highlight\_end\_tag</code>
* <code>snippet\_threshold</code>

## Options and validation

* <code>fields:</code> Array\<Symbol/String> — required. At least one non‑blank field.
* <code>full\_fields:</code> Array\<Symbol/String> — optional.
* <code>start\_tag</code>/<code>end\_tag:</code> simple HTML‑like tokens such as <code>\<em></code>, <code>\</em></code>, <code>\<mark></code>, <code>\</mark></code>. Attributes are not allowed.
* <code>affix\_tokens</code>/<code>snippet\_threshold:</code> non‑negative integers; strings of digits are coerced.

On invalid values the API raises <code>SearchEngine::Errors::InvalidOption</code> with a helpful hint.

See: <code>#options</code> in this page.

## Result helpers

Each hydrated hit gets two helpers:

* <code>hit.highlights</code> → `Hash{ field_name => [ { value:, matched_tokens:, snippet: true/false } ] }`
* <code>hit.snippet\_for(:description, full: false)</code> → HTML safe string (Rails <code>SafeBuffer</code> when present)

Safety:

* Only your configured <code>start\_tag</code>/<code>end\_tag</code> are preserved. All other markup is escaped to prevent XSS.
* If the server returns different tags, they are normalized to your configured tags.

## Troubleshooting

* Missing highlights: ensure <code>fields:</code> includes the attributes you search over and that Typesense has highlighting enabled for the collection.
* Tags not applied: invalid tags are rejected; use simple tokens like <code>\<em></code> and <code>\</em></code>.
* Snippets too long/short: adjust <code>affix\_tokens</code> and <code>snippet\_threshold</code>.

## Backlinks

* See <a href="/projects/search-engine-for-typesense/v30/dx">DX</a> for DX helpers (<code>to\_params\_json</code>, <code>dry\_run!</code>, <code>explain</code>).
* See <a href="/projects/search-engine-for-typesense/v30/relation-reference">Relation Guide</a> and <a href="/projects/search-engine-for-typesense/v30/cookbook-queries">Cookbook Queries</a> for composing DSL calls.
* See <a href="/projects/search-engine-for-typesense/v30/observability">Observability</a> for event names.
* Related: <a href="/projects/search-engine-for-typesense/v30/faceting">Faceting</a> if you combine facets and highlighting.
