Download the PHP package wapplersystems/meilisearch without Composer

On this page you can find all versions of the php package wapplersystems/meilisearch. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package meilisearch

ws_meilisearch — Meilisearch — Search, Hybrid & RAG

TYPO3 v14 extension providing Meilisearch-backed full-text search via the SEAL abstraction. Designed so the search backend stays swappable (Meilisearch today, Typesense / Elasticsearch tomorrow) without rewriting templates or services.

Features at a glance

Indexing

Search

Frontend surfaces

Retrieval-Augmented Generation (RAG)

Quality assurance

Operations

System requirements

Component Version Notes
TYPO3 ^14.0 uses v14 PSR-7 attribute container, Site Settings typed identifiers, Locale value object
PHP ^8.2 readonly properties, enums, mixed returns
Meilisearch >= 1.12 needs /similar, disableOnWords, disableOnNumbers, swap-indexes; v1.47+ recommended for stable embedder pipeline
Apache Tika optional, >= 2.x recommended required only for FAL text extraction (PDF / Office / RTF / EPUB)
Composer deps cmsig/seal ^0.12, cmsig/seal-meilisearch-adapter ^0.12, meilisearch/meilisearch-php ^1.10, lochmueller/index ^2.0, patrickschur/language-detection ^5.3 pulled in via this package's composer.json
Embedder (optional) any OpenAI-compatible /v1/embeddings endpoint tested with Scaleway Generative APIs, Infomaniak AI Tools, OpenAI, Ollama, Mistral La Plateforme
LLM (optional, for RAG) OpenAI-compatible /v1/chat/completions OpenAI, Anthropic, Mistral / Scaleway, Ollama, Infomaniak
Database MariaDB 10.5+ / MySQL 8.0+ uses JSON columns + utf8mb4 collation; standard TYPO3 v14 baseline
DDEV (local dev) >= 1.22 ships .ddev/docker-compose.meilisearch.yaml + docker-compose.tika.yaml

Installation

The extension lives as a local package in packages/wapplersystems/meilisearch/, already picked up by the root composer.json. To install:

This pulls in:

DDEV setup

Two services drop into .ddev/:

After ddev restart:

Configuration

Enable the Site Set on the desired site in config/sites/<id>/config.yaml:

Then set the connection in config/sites/<id>/settings.yaml:

deduplicateFiles defaults to false (every site indexes every FAL file). Set to true for strict per-site results — the indexer then follows sys_file_reference → page → site and only includes files referenced from at least one page of the current site. Files referenced only from non-page records (e.g. be_users.avatar) are skipped entirely.

Index filtering

Three optional settings under meilisearch.indexing keep junk files (icons, configs, backups) out of the corpus. They run at the iterator level in FileSchemaProvider, so filtered files never become docs — no wasted Tika roundtrips, faster reindex.

The three filters compose: a file must pass the extension gate (whitelist if set, otherwise blacklist) AND the image-size gate before being eligible for indexing. Comparison is case-insensitive and leading dots are stripped (.YAML matches yaml).

Definitions live in Configuration/Sets/WsMeilisearch/settings.definitions.yaml so settings are typed and editable through the Backend Sites module.

Hybrid search (Phase 3)

To enable vector + keyword hybrid search, set meilisearch.embedder.* in the site settings and enable the vectorStore experimental feature on the Meilisearch server (one-time, server-wide):

Then pick a source:

ws_meilisearch:reindex --rebuild pushes the embedder configuration to Meilisearch before populating documents, so the first hybrid query after rebuild sees a fully vectorized corpus. Note that --rebuild drops the index and therefore throws away every existing vector — everything is re-embedded from scratch. Without it, the reindex writes in place and only pays for documents that actually changed (see Incremental re-indexing).

Incremental re-indexing (what a reindex actually costs)

Every document carries two fingerprints, written by DocumentBatchWriter:

field covers
docHash the whole document except the vector — "nothing changed"
embedHash the exact text sent to the embedder + embedder identity (source, model, dimensions, maxInputChars) — "the stored vector is still the right one"

Before writing a batch, the indexer reads those two fields back for the documents it is about to push (a cheap request — ids and two short strings, no vectors) and then decides per document:

Vectors are only transferred for the middle case, in a second request — a 3584-dimension vector is ~70 KB of JSON, so fetching them unconditionally would trade a token bill for a bandwidth bill.

This is what makes re-indexing a large corpus affordable. Without it, every full reindex re-embeds every document: on a 45.000-document index against a rate-limited provider that means the run stalls in a silent 429 retry loop and never finishes.

The CLI reports the breakdown, so a run that is about to become expensive is visible immediately:

Bootstrap. Documents indexed before fingerprinting existed carry neither hash. A document that has a vector of the expected dimension is adopted: its vector is treated as current and re-used, so the first run after upgrading costs zero embeddings. Pass --force-embed to re-embed regardless — needed after an embedder model change, and the one flag that can exhaust a provider quota on purpose.

Zero-downtime mode (meilisearch.indexing.zeroDowntime) cannot skip: every document has to land in the draft index or the swap would publish an index with holes. Fingerprints and vectors are then read from the primary and copied into the draft — still no embedding cost, but the vectors do go over the wire.

Rate control and failure handling

With meilisearch.embedder.precompute: true the embeddings are fetched by PHP, so this integration owns the call rate:

tokensPerMinute is the setting that matters on providers that meter tokens rather than requests (Scaleway answers INSUFFICIENT QUOTA … quota tokens per minute. Slow down). A requests-per-minute cap does nothing against it: a handful of full page texts can exhaust a minute's token budget in a single call.

You usually do not have to configure it. Every response carries the provider's own accounting, and it is trusted over the local estimate:

The reported limit becomes the default budget, and a request that no longer fits into remaining waits out reset before it is sent. The local chars/4 estimate only has to carry the very first call; from then on the numbers are the provider's. If the provider answers 429 anyway, the retry path honours Retry-After, clears the window and backs off.

For scale: at 200.000 tokens/minute, re-embedding a 45.000-document corpus of ~2000 tokens each takes over seven hours of uninterrupted provider time. That is the bill the fingerprinting above avoids.

maxInputChars bounds a single document's contribution. It is part of embedHash, so changing it invalidates the cached vectors and the affected documents are re-embedded on the next run.

Failures are loud. With a userProvided embedder Meilisearch rejects any document that arrives without _vectors.default, and it does so asynchronously in its own task queue — a vectorless push looks successful from PHP while the document never lands. Documents whose embedding failed are therefore not pushed at all:

Frontend: ?hybrid=1 on the results URL flips to hybrid mode; the hybridAvailable flag is exposed to Fluid so the toggle stays hidden on sites without an embedder. semanticRatio (0..1) is read from site settings and can be overridden per request via the options parameter of SearchService::search().

Relevance boosting

Two independent knobs let you push some documents above others at equal text relevance. They compose multiplicatively into a single boost float stored on every document, which Meilisearch sorts on via the boost:desc custom ranking rule.

Per-type (integrator), Site Settings — meilisearch.boosts.types.<type>, one float per document type (1.0 = neutral):

Per-record (editor), backend field — tx_wsmeilisearch_boost, a 5-step select on pages, tx_news_domain_model_news and tx_wsmeilisearch_knowledge_resource (tab "Search"). Editors pick a relative weight; the indexer multiplies it onto the type default:

Setting Multiplier
Very low 0.5×
Low 0.75×
Normal (default) 1×
High 1.5×
Very high 2×

Example: a High news article (1.5) of a type weighted 1.2 ends up at boost = 1.8. Honoring the editor field can be switched off with meilisearch.boosts.recordOverrideEnabled: false (type defaults still apply). Tables without the field (e.g. sys_file, whatsnew) use the type default only.

Activation: the boost field is always written, but only influences ranking once boost:desc is present in meilisearch.defaults.rankingRules — place it before attribute so it breaks ties before the match-position rule:

boost:desc is a tie-breaker: it reorders documents that are otherwise equal on words/typo/proximity. A file with a genuinely stronger text match still outranks a higher-boosted page — boost cannot rescue a weaker hit, only order equally-relevant ones. Changing per-type values or the ranking rule needs ws_meilisearch:apply-settings; changing a record's field re-indexes that record automatically on save (back-fill a whole type with ws_meilisearch:index-record <table>). The editor field is labelled and described inline in the backend (EN + DE).

Retrieval-Augmented Generation (Phase 4)

Pick an LLM provider in site settings and the WsMeilisearch / Rag Extbase plugin becomes a "ask the site" chat. Search runs first (hybrid by default if an embedder is configured); the top hits become context for the LLM, which returns a grounded answer with [id=...] citation markers.

Citations: the default system prompt instructs the LLM to mark facts with [id=<hit-id>] and the controller extracts them via regex, returning a citedIds list alongside the rendered answer so the template can show a "Sources" block.

Caching / replay: listen to BeforeLlmCallEvent and set $response to a cached value to skip the LLM call entirely. Useful for tests and for FAQ-style questions that don't need a fresh generation per visit.

CLI for debugging without rendering the FE plugin:

Multi-turn conversation memory (opt-in):

When enabled, the controller stores the last N (question, answer) pairs in the anonymous TYPO3 frontend user session (cookie-backed by TYPO3 itself). RagService splices them between the system prompt and the new user turn, so the LLM sees: [system, prior_user, prior_assistant, …, current_user_with_context]. A new ?action=reset URL on the RAG plugin clears the stored state so a visitor can start over. Sources from past turns are not re-displayed; the controller only keeps citedIds for the template to show as "this answer cited X".

Backend module (Phase 5)

After installing the extension, an admin-only entry System → Meilisearch shows up. The overview action lists every site with:

The Test search & RAG sub-page lets an editor type a query and an LLM question against any site without leaving the BE — useful for verifying that a freshly tuned documentTemplate or systemPrompt behaves as expected before pushing settings to production.

The Diagnostics sub-page shows, per site, the desired embedder configuration (from settings.yaml) next to the actual one stored on the Meilisearch server, plus the configured RAG provider with its model / URL / conversation-memory flags. Two maintenance buttons:

Help-doc importers

Beyond the auto-indexed core record types (pages, news, FAL files), the extension ships a generic help-doc record type (tx_wsmeilisearch_helpdoc, type=help in the unified index) and five pluggable importers that populate it from very different sources. The intent: a single search + RAG corpus that can absorb a vendor's DITA documentation, an editor's PDF upload, a fileadmin sync, a zip drop, and an external URL list — without each source needing its own schema or controller.

All importers extend a single contract (HelpDocSourceImporter) and are picked up via DI auto-tagging. Adding a sixth source means implementing the interface — no controller / CLI / template changes.

Built-in importers

Slug Source Best for Picker
dita-ot DITA-OT XHTML drop on disk Strukturierte help topics with TOC + per-topic media Target media folder
single-file One PSR-7 upload Editor pastes a single curated PDF / DOCX / Markdown Target folder
folder FAL folder walk Files dropped into fileadmin via FileList / FTP / sync Source folder + Target folder
zip-bundle One PSR-7 zip upload A stack of mixed docs delivered as one archive Target folder
url-list HTTP fetch a list of URLs Seeding from public docs sites / S3 PDF lists / wikis Target folder

Common behaviour:

Configuration

Two site settings drive the help-doc pipeline:

tx_wsmeilisearch_helpdoc is shipped by ext_tables.sql and registered in indexedTables by default — running ws_meilisearch:reindex after the first import pushes the rows into the unified per-site index.

Backend workflow

The Help docs tab on the System → Meilisearch module gives operators one form per importer slug:

The Purge by language card next to these forms hard-deletes every helpdoc row in the chosen language with a confirm-checkbox guard. Reindex is not triggered automatically — every form trailer reminds the operator to run ws_meilisearch:reindex (or use the Overview tab) afterwards.

The Browse buttons on every folder field open TYPO3's standard FAL folder picker as a modal. The modern URL parameters (?fieldReference=…&useEvents=1) are used instead of the legacy bparams pipe-string, so the picker dispatches a CustomEvent on its iframe and avoids the postMessage origin gauntlet inherent to nested backend modals.

CLI workflow

The dispatch CLI is ws_meilisearch:import-help-docs. The --importer=<slug> switch picks the implementation; every other parameter is interpreted via the importer's describeFields() schema.

The CLI prints a progress bar per item, lists every per-item failure verbatim (Tika skip, HTTP error, FAL consistency rejection, …), and returns the imported / skipped / mediaCopied triple in the final success line. Generic -f name=value pairs always override the shorthand options.

Safety notes per importer

Adding a custom importer

Implement HelpDocSourceImporter in your extension's Classes/Service/Import/Importer/:

The _instanceof rule in Configuration/Services.yaml auto-tags it as ws_meilisearch.source_importer, so it appears in both --list-importers and the BE Help-docs tab without further wiring. Use the injected HelpDocRepository for FAL + Tika + persistence — the helpers handle target-folder auto-creation, sanitisation, and the standard media reference attachment.

RAG quality regression

Editor-maintained (question, expected answer, threshold) triples live in tx_wsmeilisearch_ragtest. The runner asks the configured RAG provider each question, embeds expected + actual via the site's embedder, and scores cosine similarity against the per-row similarity_threshold — pass / fail / error. Idempotent and safe to run on cron; the same engine is reachable from three places so ad-hoc triage and unattended runs never drift.

Three trigger paths, one engine

Trigger When to use
BE tab "RAG tests" Ad-hoc triage. Per-row Run button + global Run-all. Sparkline column shows the last ~30 score points so trends are visible at a glance.
CLI ws_meilisearch:run-rag-tests [site] [--show-answers] One-shot from a deploy script or local checking. Distinct exit codes (0 / 1 / 2) for cron — see "Exit-code taxonomy" below.
Scheduler task Meilisearch: RAG regression tests Periodic monitoring. TYPO3-native v14 task; reuses tx_wsmeilisearch_site_identifier. Returns false on any FAIL so the scheduler flags the run; ERROR-only runs stay true (infrastructure hiccup, not regression).

Threshold-tuning is per-test

Cosine similarity scores depend heavily on the embedder and on text length. 0.85 is a sane default for nomic-embed-text on full-paragraph expected answers; short German texts often score 0.80+ even on semantically-unrelated content because of shared vocabulary. The operator picks the threshold per row based on how strict the match needs to be:

Embedding clients

HelpDocSourceImporter-style plugin pattern. The right client is picked by matching meilisearch.embedder.source against each registered client's supports() vote:

Source slug Endpoint
ollama Native /api/embeddings (not the OpenAI-compatible /v1/... route — they share a host but expect different request shapes)
openAi /v1/embeddings with bearer token; default URL https://api.openai.com/v1/embeddings
infomaniak /1/ai/<productId>/openai/v1/embeddings — URL built from meilisearch.infomaniak.productId; same key as RAG / Meilisearch embedder

Add another provider by implementing EmbeddingClientInterface; the _instanceof rule in Services.yaml auto-tags it and the registry picks it up.

Per-run history + sparklines

Every run also writes a row to tx_wsmeilisearch_ragtest_run (test uid, status, score, actual answer, crdate). A rolling per-test prune keeps the table at RagTestRunner::HISTORY_KEEP=100 rows so growth is bounded without operator cron. The BE tab pre-renders an inline SVG sparkline of the last 30 scores per test — Y axis is fixed 0..1 so two sparklines compare visually across tests, and the <title> carries count / min / max / last for hover detail.

Exit-code taxonomy (CLI + scheduler)

Exit Meaning
0 All PASS
1 At least one FAIL — real quality regression. Cron monitor latches.
2 Errors only (RAG provider down, embedder down, transport hiccup). NOT a quality signal — re-run after the underlying fix.

Same distinction maps to the scheduler task return value: false only when a FAIL happened; ERROR-only runs stay true so the scheduler doesn't latch on transient infrastructure noise.

Quota checks for commercial providers

ws_meilisearch:check-quotas walks every site, fans out to a QuotaProvider per configured commercial backend (Infomaniak / OpenAI / Anthropic), and emails a warning when usage crosses meilisearch.quota.threshold (default 80%). Idempotent — only emails when over threshold. Exit 1 when any provider is over, so cron monitors latch.

Configuration

Infomaniak limitation: Verified 2026-06-07 against Infomaniak's production API with a Manager-scope token: there is currently NO usage endpoint for AI Tools. /1/ai returns product reachability

Adding a custom provider

Implement QuotaProviderInterface, return QuotaStatus::ok(...) / ::error(...). The _instanceof tag auto-registers it; the runner dispatches by matching the site's configured provider slug.

Scheduler task (Phase 5)

FullReindexTask registers under Administration → Scheduler as Meilisearch: Full Reindex. TYPO3 v14 native task — fields are TCA-driven on tx_scheduler_task, no AdditionalFieldProviderInterface:

Typical cadences:

CLI

Keeping the crawl queue consumed (production)

Page indexing is asynchronous: index:queue only enqueues work, and the bridge writes to Meilisearch when a worker consumes the message. Without a permanent consumer the queue silently grows and the page corpus goes stale without a single error anywhere — no failed task, no log entry, just an index that stops changing. On the LINEAR production host that went unnoticed for ten days and 8.675 messages.

Do not schedule this with cron. Use a systemd template so a dead worker is replaced in seconds rather than at the next tick, and so systemctl status and journald give you a handle on it:

Three points that are easy to get wrong:

What's wired

Layer Component File
Plugin registration Extbase plugin WsMeilisearch / Search (CType wsmeilisearch_search) ext_localconf.php, Configuration/TCA/Overrides/tt_content.php
Site Set wapplersystems/ws-meilisearch with typed settings + TypoScript Configuration/Sets/WsMeilisearch/*
Indexing extension point SchemaProviderInterface (auto-tagged via _instanceof) Classes/Domain/Schema/
Default providers tx_news (gated on EXT:news) + sys_file (one doc per site language with sys_file_metadata overlay) + knowledge resources (type: knowledge_resource). Pages are indexed via the bundled Integration/ExtIndex on top of lochmueller/index. NewsSchemaProvider.php, FileSchemaProvider.php, KnowledgeResourceSchemaProvider.php, Classes/Integration/ExtIndex/EventListener/IndexEventListener.php
Project provider (LINEAR) tx_linearproducts_domain_model_whatsnew → type: whatsnew. Multilingual inline (one row, name_<x>/description_<x>/media_<x> for de/en/tr/ru/nl/pl → one doc per filled language; fr/it skipped). No detail view: uri deep-links to the list page with ?…[whatsnew]=<uid>. Type boost via meilisearch.boosts.types.whatsnew. WhatsnewSchemaProvider.php
Engine factory Reads site settings, builds unified SEAL Engine + Index Classes/Service/SearchEngineFactory.php
Indexer Iterates providers, dispatches lifecycle events, waits on Meilisearch async tasks Classes/Service/IndexerService.php
Search service Builds SEAL query (search + filters + facets), maps result; hybrid path bypasses SEAL to use Meilisearch SDK directly Classes/Service/SearchService.php
Tika integration Apache Tika REST client + sha1-keyed cache Classes/Service/Tika/
Embedder configurator Idempotent PATCH of per-index embedder settings, source-aware field allowlist, waits for async settingsUpdate Classes/Service/EmbedderConfigurator.php
LLM provider abstraction LlmProviderInterface with OpenAI / Anthropic / Ollama / generic REST implementations, picked per site by LlmProviderRegistry Classes/Service/Llm/
RAG orchestrator Retrieves hits → builds cited-context prompt → calls LLM → parses [id=...] citations → RagAnswer DTO Classes/Service/Rag/
RAG plugin Extbase plugin WsMeilisearch / Rag (CType wsmeilisearch_rag) with form + ask + reset actions Classes/Controller/RagController.php
RAG streaming SSE endpoint at /_ws_meilisearch/rag/stream, drop-in JS client renders tokens incrementally Classes/Middleware/RagStreamMiddleware.php, Resources/Public/JavaScript/RagStream.js
RAG CLI ws_meilisearch:ask "question" [site] for ad-hoc testing Classes/Command/AskCommand.php
Diagnostics CLI ws_meilisearch:doctor / :setup-index-config / :document / :tika-probe for operator triage Classes/Command/DoctorCommand.php, SetupIndexConfigCommand.php, DocumentCommand.php, TikaProbeCommand.php
Backend module System → Meilisearch: per-site index status, Reindex / Rebuild buttons, ad-hoc Search + RAG test forms, Help-doc importer dashboard Classes/Controller/Backend/OverviewController.php
Help-doc importers Plugin architecture for populating tx_wsmeilisearch_helpdoc from DITA-OT drops, single uploads, FAL folders, ZIP bundles, URL lists Classes/Service/Import/HelpDocSourceImporter.php, Classes/Service/Import/Importer/*
Help-doc CLI ws_meilisearch:import-help-docs --importer=<slug> dispatcher with per-importer field schema Classes/Command/ImportHelpDocsCommand.php
FAL folder picker data-wsm-folder-picker button opens TYPO3's standard element-browser modal; writes the combined identifier back into the bound input via the picker's CustomEvent Resources/Public/JavaScript/folder-picker.js, Configuration/JavaScriptModules.php
RAG regression runner Run one or many (question, expected, threshold) rows, embed via the configured EmbeddingClient, score cosine, persist per-test state + rolling history. Shared by CLI, scheduler, BE tab. Classes/Service/RagTest/RagTestRunner.php, Classes/Service/RagTest/EmbeddingClient*.php
RAG regression CLI ws_meilisearch:run-rag-tests [site] [--show-answers] with pass / fail / error exit codes for cron Classes/Command/RunRagTestsCommand.php
RAG regression scheduler task TYPO3 v14 native task — same engine + return value false on FAIL, true on ERROR-only Classes/Task/RunRagTestsTask.php
RAG regression BE tab ?action=ragtests: per-test state table with sparklines, Run-now / Run-all, summary badges, New-test deep link Classes/Controller/Backend/RagTestController.php, Resources/Private/Templates/Backend/Overview/RagTests.html
Quota check CLI ws_meilisearch:check-quotas [site] [--dry-run] — fans out to QuotaProvider per configured commercial backend, emails over-threshold Classes/Command/CheckQuotasCommand.php, Classes/Service/Quota/*
Scheduler task TYPO3 v14 native task (TCA-driven, no AdditionalFieldProvider) for periodic reindex of one site or all Classes/Task/FullReindexTask.php
Realtime sync (BE forms) DataHandler hook → indexer (sys_file_metadata + sys_file_reference both translated to sys_file) Classes/DataHandling/RecordChangeListener.php
Realtime sync (FAL storage) PSR-14 listeners on AfterFileAdded / Deleted / Renamed / Moved / ContentsSet / Replaced / Copied / MetaDataUpdated / RemovedFromIndex Classes/DataHandling/FalEventListener.php
Cross-site file dispatcher Shared reindex(uid) / remove(uid) used by both sync paths Classes/DataHandling/FileLifecycleHandler.php
CLI ws_meilisearch:reindex [site] [--rebuild] Classes/Command/ReindexCommand.php
CLI (scoped) ws_meilisearch:index-record <table> [uid] [site] [--remove] — one record or whole table, no schema rebuild Classes/Command/IndexRecordCommand.php
Events (PSR-14) Before/After Document Indexed, Before/After Search Classes/Event/
Frontend templates GET-only forms, auto-submit facets, PRG-redirect on stray POSTs Resources/Private/Templates/Search/

Examples

End-to-end snippets in Examples/ — pick the closest match to your setup and adapt:

File Topic
01 Minimal keyword search
02 FAL files via Apache Tika
03 Hybrid search with OpenAI embeddings
04 Hybrid search with self-hosted Ollama
05 RAG chat with Anthropic Claude
06 Multi-turn RAG conversation memory
07 Cache identical RAG calls via BeforeLlmCallEvent
08 Rewrite verbose user queries before retrieval
09 Index a third-party extension's records
10 Call SearchService / RagService from PHP
11 RAG streaming via Server-Sent Events
12 OCR for scanned PDFs + images
13 Sort dropdown + pagination in the FE plugin

Frontend plugin invariants

Per-instance overrides via FlexForm

The Search plugin ships a FlexForm so the same wsmeilisearch_search CType can be configured differently per content element. Every field is optional — empty inherits from the Site Settings default.

FlexForm field Overrides Notes
Visible facets meilisearch.facets Comma-separated attribute list (e.g. type,language)
Results per page meilisearch.frontend.perPage Int 0..500. 0 inherits the site default
Default sort (none — initial sort) One of: Relevance, datetime desc/asc, fileSize desc/asc. Visitor's ?sort= param still wins
Restrict to current language meilisearch.restrictToCurrentLanguage Tri-state: Inherit / Force ON / Force OFF

Useful when a per-language search page wants the language filter forced on while the global search page wants cross-language results — same install, same site settings, different plugin instances.

Adding a new record type

Implement SchemaProviderInterface. Auto-wired and auto-tagged via _instanceof in Configuration/Services.yaml, no manual registration.

Optional getAdditionalFields() lets a provider contribute extra SEAL schema fields (e.g. price as IntegerField sortable + filterable). The factory dedupes by field name across providers.

Roadmap

Done:

Open / under consideration:

Limitations

Hybrid / embedder

RAG

Indexing


All versions of meilisearch with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
typo3/cms-core Version ^14.0
typo3/cms-backend Version ^14.0
typo3/cms-extbase Version ^14.0
typo3/cms-fluid Version ^14.0
typo3/cms-frontend Version ^14.0
typo3/cms-scheduler Version ^14.0
cmsig/seal Version ^0.12
cmsig/seal-meilisearch-adapter Version ^0.12
meilisearch/meilisearch-php Version ^1.10
lochmueller/index Version ^2.0
patrickschur/language-detection Version ^5.3
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package wapplersystems/meilisearch contains the following files

Loading the files please wait ...