> For the complete documentation index, see [llms.txt](https://docs.boldminded.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.boldminded.com/dexter/docs-statamic/configuration.md).

# Configuration

Algolia and Meilisearch both provide admin interfaces to configure an index and its searchable properties. There is no need for Dexter to replicate those administration features in the Statamic control panel. Use the native interface of your chosen provider to define which properties are searchable, filterable, faceted, and so on. It is easiest to do this after one or more items have been indexed. When Dexter sends a JSON object to either provider, it automatically creates documents in the index that map to that object.

{% hint style="info" %}
**BoldMinded cannot offer support on how to configure indexes at the provider, or how to write custom pipelines. For pipeline guidance, refer to the `Pipeline` directory in Dexter for examples.**
{% endhint %}

#### What gets indexed

Dexter indexes four kinds of Statamic content, referred to as **scopes**:

| Scope        | Statamic content      | Searchable key      |
| ------------ | --------------------- | ------------------- |
| `entries`    | Collection entries    | `collection:handle` |
| `categories` | Taxonomy terms        | `taxonomy:handle`   |
| `files`      | Assets in a container | `assets:handle`     |
| `users`      | Users                 | `users`             |

The scope names come from Dexter's shared core, which is why taxonomy terms are configured under a scope called `categories` — the name matches the ExpressionEngine and Craft builds.

Indexing runs automatically when content is saved or deleted. Dexter listens for these Statamic events:

<table data-search="false"><thead><tr><th>Event</th><th>Action</th></tr></thead><tbody><tr><td><code>EntrySaved</code>, <code>EntryScheduleReached</code></td><td>Index</td></tr><tr><td><code>EntryDeleted</code></td><td>Remove</td></tr><tr><td><code>TermSaved</code></td><td>Index</td></tr><tr><td><code>TermDeleted</code></td><td>Remove</td></tr><tr><td><code>AssetSaved</code>, <code>AssetUploaded</code>, <code>AssetReplaced</code>, <code>AssetReuploaded</code></td><td>Index</td></tr><tr><td><code>AssetDeleted</code></td><td>Remove</td></tr><tr><td><code>UserSaved</code></td><td>Index</td></tr><tr><td><code>UserDeleted</code></td><td>Remove</td></tr></tbody></table>

Set `enabled` to `false` to stop indexing on save and delete. Console commands still run, which is useful while seeding or migrating content.

#### Nested fields

This is the main reason to reach for Dexter over native search. Field lists support dot notation and wildcards, so nested content is addressable:

```php
'collection:pages' => [
    'fields' => [
        'title',
        'subtitle',
        'permalink',

        // Nested Replicator. The wildcard spans every set type; sets
        // without the field simply contribute nothing.
        'page_builder.*.title',
        'page_builder.*.subtitle',
        'page_builder.*.image',
        'page_builder.*.text_column_*',

        // Prefixed group import: every field in the group whose handle
        // begins with contact_.
        'contact_settings.contact_*',
    ],
],
```

Fieldtypes needing special handling have a dedicated extractor: Bard, Replicator, Grid, Group, Assets, Markdown, and the relationship fieldtypes (`entries`, `terms`, `users`, `taxonomies`, `collections`). Everything else falls back to scalar extraction, which is correct for the great majority of Statamic fieldtypes.

To see exactly what Dexter would send to the provider, without contacting one:

```bash
php please dexter:preview --limit=3
```

#### Multi-site

Dexter handles multi-site in one of two ways, per index.

**One index for every locale.** The default. Each document carries a `site` field, and you filter by it at query time.

**One index per locale.** Add a `sites` key to the index. The locale becomes part of the resolved index name, so `content` becomes `production_content_fr`.

```php
'indexes' => [
    'content' => [
        'driver' => 'meilisearch',
        'sites' => 'all', // or ['default', 'fr']
        'searchables' => [
            // ...
        ],
    ],
],
```

Every localization of an entry is indexed. Each is its own document with its own unique id, so there is no duplication to guard against.

Entries and terms carry a locale and route to the localized index. Assets and users do not carry a site, so they are always written to the unlocalized index name, even when the index declares `sites`.

#### Full text

With `includeFullText` enabled, Dexter adds a `__full_text` property to each document, containing all indexed text concatenated together. This is useful for full-text search, and required for semantic search and for document and image parsing.

Stop words are removed from `__full_text`. A default English list ships in the config. On a multilingual site, set `stop_words` to an empty array — an English list strips nothing useful from other languages, and may remove words that are meaningful in them.

#### Queue

Indexing on save writes to the search provider inline by default. Set `queue` to `true` and saves dispatch a queued job instead, so a slow provider never blocks a content save. This requires a running queue worker.

Deletes always run inline. They are a single cheap call, and queueing them would race the content's removal.

For a full rebuild, use the `--queue` flag rather than changing the config:

```bash
php please dexter:reindex content --queue
```
