---
title: "Flexsearch Query Regex Building"
description: "The flexsearchI18n to buildRegexFromQuery execution flow handles multi-language document searching and result highlighting in Fumadocs. When a user submits a search query with internationalization ..."
last_updated: "2026-10-12T07:53:59.756147+00:00"
canonical_url: "https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/technical/how-it-works/flexsearch-query-regex-building"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [packages/core/src/search/flexsearch.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/flexsearch.ts)
- [packages/core/src/search/flexsearch/utils.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/flexsearch/utils.ts)
- [packages/core/src/search/index.ts](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/index.ts)
</details>

## Overview

### Introduction

The `flexsearchI18n` to `buildRegexFromQuery` execution flow handles multi-language document searching and result highlighting in Fumadocs. When a user submits a search query with internationalization (i18n) enabled, the request is routed through language-specific FlexSearch document indices, executed against the search engine, and post-processed with content highlighters that convert terms into regular expressions. This pipeline ensures that search results respect locale boundaries and feature appropriately highlighted matched terms.

Sources: [packages/core/src/search/flexsearch.ts:72-129](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/flexsearch.ts#L72-L129), [packages/core/src/search/flexsearch/utils.ts:7-68](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/flexsearch/utils.ts#L7-L68), [packages/core/src/search/index.ts:36-43](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/index.ts#L36-L43)

## Execution Flow

### Step 1: flexsearchI18n

The execution begins when `flexsearchI18n` is invoked with `I18nOptions`. This function acts as the public entrypoint for setting up an internationalized search endpoint. It wraps the core `serverI18n` implementation inside an endpoint creator and returns a `SearchAPI` interface.

Sources: [packages/core/src/search/flexsearch.ts:135-137](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/flexsearch.ts#L135-L137)

### Step 2: serverI18n

`serverI18n` takes the i18n configuration options and initializes search servers for each locale. It defines the `export` and `search` handlers. When a `search` request arrives, it resolves the appropriate language server using `searchOptions.locale` or falls back to `options.i18n.defaultLanguage`. If a matching language handler is found, it delegates the query to that specific server instance.

Sources: [packages/core/src/search/flexsearch.ts:72-129](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/flexsearch.ts#L72-L129)

### Step 3: initSearchServers

Inside `serverI18n`, the asynchronous `initSearchServers` function groups the provided document indexes by their locale. If `inputIndexes` is provided as an asynchronous function, it awaits the result. It then iterates over the grouped indexes, applies any locale-specific overrides (such as CJK character encoding options), and instantiates a standard single-language `server` for each locale, storing them in a `Map<string, SearchServer>`.

Sources: [packages/core/src/search/flexsearch.ts:75-105](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/flexsearch.ts#L75-L105)

### Step 4: server

The single-language `server` function manages the FlexSearch document index for a specific locale. It initializes the search index via `createDocument`, populates it with documents, and exposes `export` and `search` methods. When `search` is called, it awaits the index initialization promise and passes the query and options to the search utility.

Sources: [packages/core/src/search/flexsearch.ts:41-70](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/flexsearch.ts#L41-L70)

### Step 5: search

The `search` utility function in `flexsearch/utils.ts` executes `index.searchAsync()` against the FlexSearch document store. If results are returned, it invokes `createContentHighlighter(query)` to prepare highlighters. It then groups matching sections by page ID, builds formatted results including page metadata, and highlights matching content markdown before returning the final sorted results array.

Sources: [packages/core/src/search/flexsearch/utils.ts:7-68](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/flexsearch/utils.ts#L7-L68)

### Step 6: createContentHighlighter

`createContentHighlighter` accepts the search query (or a prebuilt RegExp) and returns highlighting utilities. If a string query is passed, it delegates immediately to `buildRegexFromQuery` to compile the search terms into a case-insensitive regular expression.

Sources: [packages/core/src/search/index.ts:47-49](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/index.ts#L47-L49)

### Step 7: buildRegexFromQuery

`buildRegexFromQuery` takes the raw query string, trims whitespace, and splits it into unique terms by whitespace. It escapes any special regular expression characters in each term using `escapeRegExp`, joins them with the alternation operator (`|`), and returns a compiled global, case-insensitive `RegExp` object (or `null` if the query is empty).

Sources: [packages/core/src/search/index.ts:36-43](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/index.ts#L36-L43)

## Architecture Diagrams

### Sequence Diagram

```mermaid
sequenceDiagram
    participant Client
    participant FlexsearchI18n as flexsearchI18n (flexsearch.ts)
    participant ServerI18n as serverI18n (flexsearch.ts)
    participant InitServers as initSearchServers (flexsearch.ts)
    participant Server as server (flexsearch.ts)
    participant SearchUtil as search (flexsearch/utils.ts)
    participant Highlighter as createContentHighlighter (index.ts)
    participant RegexBuilder as buildRegexFromQuery (index.ts)

    Client->>FlexsearchI18n: flexsearchI18n(options)
    FlexsearchI18n->>ServerI18n: serverI18n(options)
    Note over ServerI18n,InitServers: Search request triggers server initialization
    ServerI18n->>InitServers: initSearchServers()
    InitServers->>Server: server(localeOptions)
    
    Client->>ServerI18n: search(query, searchOptions)
    ServerI18n->>Server: search(query, searchOptions)
    Server->>SearchUtil: search(index, query, tag, limit)
    SearchUtil->>Highlighter: createContentHighlighter(query)
    Highlighter->>RegexBuilder: buildRegexFromQuery(query)
    RegexBuilder-->>Highlighter: RegExp
    Highlighter-->>SearchUtil: highlighter instance
    SearchUtil-->>Server: SortedResult[]
    Server-->>ServerI18n: SortedResult[]
    ServerI18n-->>Client: SortedResult[]
```

Sources: [packages/core/src/search/flexsearch.ts:41-137](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/flexsearch.ts#L41-L137), [packages/core/src/search/flexsearch/utils.ts:7-68](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/flexsearch/utils.ts#L7-L68), [packages/core/src/search/index.ts:36-49](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/index.ts#L36-L49)

### Flowchart

```mermaid
flowchart TD
    A[flexsearchI18n] --> B[serverI18n]
    B --> C[initSearchServers]
    C -->|Group by locale & override| D[server]
    D -->|Execute search| E[search util]
    E -->|Create highlighter| F[createContentHighlighter]
    F -->|Parse query string| G[buildRegexFromQuery]
    G -->|Valid terms?| H{Yes / No}
    H -->|Yes| I[Return RegExp]
    H -->|No| J[Return null]
    I --> K[Highlight Markdown / Text]
    J --> K
    K --> L[Return Sorted Results]
```

Sources: [packages/core/src/search/flexsearch.ts:41-137](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/flexsearch.ts#L41-L137), [packages/core/src/search/flexsearch/utils.ts:7-68](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/flexsearch/utils.ts#L7-L68), [packages/core/src/search/index.ts:36-49](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/index.ts#L36-L49)

## Key Observations

- **Cross-Module Boundaries:** The flow bridges higher-level i18n server orchestration (`flexsearch.ts`), low-level FlexSearch execution and document grouping (`flexsearch/utils.ts`), and text/Markdown parsing utilities (`index.ts`).
- **Locale Resolution and Fallback:** If a requested locale is missing during a search query, `serverI18n` gracefully falls back to `options.i18n.defaultLanguage`, or returns an empty array if no matching server handler exists.
- **Robust Query Normalization:** `buildRegexFromQuery` automatically filters out empty terms, deduplicates search keywords via `Set`, and escapes regular expression special characters to prevent syntax crashes on malformed queries.

Sources: [packages/core/src/search/flexsearch.ts:121-127](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/flexsearch.ts#L121-L127), [packages/core/src/search/flexsearch/utils.ts:7-24](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/flexsearch/utils.ts#L7-L24), [packages/core/src/search/index.ts:32-43](https://github.com/blade47/fumadocs/blob/a9f988897e7dc4ef3d62b2865d80da2f5607701e/packages/core/src/search/index.ts#L32-L43)

## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/e8872a72-1909-479c-b585-dc74c6e26726/llms.txt) for all pages in this wiki.
