Scry Search: Meilisearch for WordPress

Scry Search: Meilisearch for WordPress

5/5 (3 ratings) 20 active installs Updated Nov 5, 2026
Index Settings Dashboard - Manage post type indexes, view document counts, and trigger indexing operations

Index Settings Dashboard - Manage post type indexes, view document counts, and trigger indexing operations

WordPress search is fine on a small blog. On a store with tens of thousands of products, or an archive that has been growing for years, it is not. WordPress is searching the database. Shoppers miss the product they came for, or the page sits there while MySQL grinds through post_content.

Scry Search sends that search to Meilisearch, then hands WordPress normal posts back through WP_Query. You get fast keyword search, optional AI/semantic (hybrid) search, and a big extension surface, without ripping out your theme. If you can install a plugin and paste API keys, you can run it without writing code. If you ship WordPress for a living, you can bend it without forking it.

Docs (start here): DOCS.md on GitHub — every filter/action, args, return values, when it fires, plus the window.scrySearch JS API. The same file ships in the plugin zip.

Live demo: demo.scrywp.com/search-demo — the free plugin with Scry Search Facets and Scry Search Ajax.

You get over 40 PHP hooks (scry_ms_*) covering indexing, documents, index settings, federated search, autosuggest, analytics, logs, and the front-end runtime. Call sites are marked in the source.

Built for a lot of content

A huge catalog should still be searchable. That is the case this plugin is built for.

  • Search does not scan wp_posts with a SQL LIKE. Meilisearch holds the index, so a query stays a search when the library of posts or products gets large.
  • Each post type gets its own index (posts, pages, product, custom post types). A big product catalog does not have to live in the same pile of data as the blog.
  • Federated multi-search merges those indexes using the weights you set in Search Settings. Meilisearch does that merge, not a PHP loop that pulls every hit into memory and sorts it there.
  • Bulk indexing runs in batches, so a full reindex of a large catalog does not have to load every post at once. The batch size is filterable with scry_ms_bulk_index_batch_size.
  • Saves, trashing, deletes, and untrashes update the index as you go, so a big catalog does not quietly drift out of date.
  • Typo tolerance, synonyms, stop words, and ranking rules are per index. When nobody can browse the catalog by hand, that is how a misspelled product code still finds the right item.
  • The task pane is there for the long jobs. If a bulk index of a large site stalls, or a settings update fails without saying so, that drawer shows status, duration, and errors.

No theme changes. Not glued to a results UI.

Search gets upgraded without asking you to change the theme.

  • It does not replace your search results template. search.php (or whatever your theme or builder uses) still renders the results.
  • It does not require a shortcode, block, or widget. Autosuggest and highlighting are optional, and they stay off unless you turn them on.
  • Existing search forms keep working. Gutenberg Search block, classic searchform.php, Elementor/Divi/Beaver search widgets — they still POST to WordPress, and the plugin intercepts the query.

Admin-side tuning is a different story. Ranking, searchable and filterable fields, synonyms, typo tolerance, hybrid embedders, federated weights, and the rest are all in wp-admin (see below). You’re not stuck editing Meilisearch JSON by hand, and you’re not locked into a plugin-owned results page.

Under the hood the plugin hooks posts_pre_query, runs the search in Meilisearch, and hands WordPress normal WP_Post objects. Same loop, same template tags, same pagination assumptions your theme already has.

Need native WordPress search for one query? scry_ms_should_search.

Built-in semantic / hybrid search

Keyword search is the baseline. Hybrid search lives in the core plugin, not in a separate product you have to buy. Meilisearch blends full-text ranking with vector similarity, so a “fuzzy intent” query can still land on the right post or product. On a large catalog, people often don’t know the exact name of the thing they want. That is when this helps.

Per index, under Index Settings Configure Index Hybrid Search:

  • Add embedders (OpenAI, Hugging Face, Ollama, user-provided vectors, other Meilisearch-supported sources)
  • Pick which embedder to use and the semantic vs keyword ratio
  • Enable hybrid per post type — products can differ from posts

Same WP_Query path as keyword search. No second endpoint, no alternate results page. Reindex after embedder changes so the vectors exist. Analytics can record hybrid usage in search_metadata.

What you configure in wp-admin

Most of Meilisearch’s knobs are in WordPress — you don’t need to curl the instance for day-to-day tuning.

Connection — URL, admin key, optional search-only key, connection test.

Index Settings (tabbed dialog per post type):

  • Searchable fields — titles, content, excerpts, taxonomies, author, custom meta (ACF, Meta Box, etc.); drag to set relevancy order
  • Filterable fields — post type/status/author, post_date_unix, taxonomy IDs (taxonomies.<name>.id), and more for facets / advanced filters
  • Ranking rules — reorder words / typo / proximity / attribute / sort / exactness; add custom attribute:asc / attribute:desc
  • Synonyms, stop words, dictionary — nicknames, brand aliases, noise terms, multi-word tokens
  • Typo tolerance — enable/disable, min word sizes, disable on numbers / words / attributes
  • Hybrid Search — embedders and semantic ratio (see above)
  • View Raw JSON on each group when something looks off
  • Bulk index / wipe, plus a live search preview before you ship ranking changes

Search Settings — federated post-type weights (e.g. products above blog posts), optional AJAX autosuggest (with optional form class targeting), optional matched-term highlighting (.scry-ms-highlight).

Ops — task pane, Logs, Search Analytics (see For developers).

You can go live from these screens alone. The hooks are there for when a project needs something the screens do not cover.

Autosuggest + highlighting (optional front-end extras)

These are the only front-end UI pieces the plugin ships, and both are off unless you turn them on. Your theme’s results page stays yours either way. On a large site, typeahead helps someone find a product without scrolling a huge catalog. Leave it off if you don’t want it.

Autosuggest — Search Settings toggle. The front-end runtime finds forms via CSS selectors (defaults: #adminbarsearch, form[role="search"], including the core Search block). Debounced AJAX, same indexes as full search. Optional form class if you only want typeahead on specific forms. Thumbnails when a featured image exists. Extend discovery selectors with scry_ms_window_localized — details in DOCS.md. Shape data with scry_ms_autosuggest_results or markup with scry_ms_autosuggest_results_rendered.

Highlighting — optional matched-term markup in results / autosuggest (class .scry-ms-highlight). Style it in your theme; the plugin doesn’t force a look.

Indexes and federation

Each registered post type can get its own Meilisearch index (posts, pages, product, custom post types). Federated multi-search merges them with your Search Settings weights — Meilisearch’s multi-search, not a home-rolled PHP merge.

WooCommerce is a good fit when the catalog is large: select product, pick product fields and meta, and set weights if you also search posts or pages. Catalog search upgrades. Theme and checkout stay as they are.

Ops: indexing

  • Auto-index on save; remove on trash/delete; re-index on untrash. Bulk index / wipe from Index Settings. Bulk runs in batches so a large library does not have to be loaded all at once.
  • Task pane, Logs, and Search Analytics are covered under For developers below. They’re useful for site owners too, and they’re day-to-day ops tooling — which is what you want when the index is big enough that a failed job isn’t obvious from the front of the site.

For developers

If you write code on top of this, start with the docs. The full reference lives there, not in a marketing PDF.

Full hook reference + JS API: DOCS.md on GitHub

45 PHP hooks documented there (filters + actions). Names below; args, return values, and timing are in the docs. Call sites are tagged //@HOOK: scry_ms_… in the source.

Task pane — a drawer on the plugin admin screens for Meilisearch tasks on indexes this plugin owns: status, duration, errors, and paginated history. A shared Meilisearch instance won’t dump unrelated tasks into it. Useful when a bulk index of a large site stalls, or a settings update fails without saying so.

Error / debug logs — Scry Search Logs. Debug and Error levels, filterable viewer, DB-backed newest-first with load-more, API keys/tokens redacted before storage, retention + daily cleanup (or clean on demand). Hook scry_ms_log_message if you need to divert or annotate lines.

Search analytics — Scry Search Search Analytics. Dashboard with summary metrics, charts, and recent searches; optional IP anonymization / omit identifying fields; retention with WP-Cron cleanup; CSV export (admin-only, nonce-protected). Extend rows with scry_ms_analytics_event_to_insert (non-column keys go into search_metadata, including hybrid usage when enabled).

Filters — indexing / documents:

  • scry_ms_should_index, scry_ms_should_delete, scry_ms_index_prepare_document
  • scry_ms_index_names, scry_ms_index_searchable_attributes, scry_ms_index_filterable_attributes, scry_ms_index_filterable_fields
  • scry_ms_index_typo_tolerance, scry_ms_index_ranking_rules, scry_ms_index_fields, scry_ms_index_meta_keys
  • scry_ms_bulk_index_query_args, scry_ms_bulk_index_batch_size

Filters — settings:

  • scry_ms_index_settings_ajax, scry_ms_index_settings_backup
  • scry_ms_index_ranking_rules_before_update, scry_ms_index_searchable_attributes_before_update
  • scry_ms_index_synonyms_before_update, scry_ms_index_stop_words_before_update
  • scry_ms_index_filterable_attributes_before_update, scry_ms_index_dictionary_before_update, scry_ms_index_typo_tolerance_before_update

Filters — search / client:

  • scry_ms_should_search, scry_ms_meilisearch_client
  • scry_ms_multi_search_index_names, scry_ms_multi_search_query_params, scry_ms_multi_search_query, scry_ms_multi_search_queries
  • scry_ms_multi_search_federation, scry_ms_multi_search_raw_results, scry_ms_multi_search_final_results

Filters — autosuggest / admin / analytics / logs / window:

  • scry_ms_autosuggest_posts_per_page, scry_ms_autosuggest_query, scry_ms_autosuggest_results, scry_ms_autosuggest_results_rendered, scry_ms_autosuggest_localized
  • scry_ms_admin_pages, scry_ms_analytics_event_to_insert, scry_ms_should_insert_analytics_event, scry_ms_analytics_recent_searches_columns, scry_ms_analytics_recent_searches_column, scry_ms_log_message, scry_ms_window_localized

Actions:

  • scry_ms_after_index_document, scry_ms_after_delete_document, scry_ms_after_bulk_index, scry_ms_after_create_index
  • scry_ms_index_settings_restore, scry_ms_index_update_settings, scry_ms_index_settings_sections_ui

JS: window.scrySearch (handle scry_ms_window-script). Wait for scrySearchReady. Forms from windowLocalized.searchFormSelectors; filter scry_ms_window_localized to add selectors (e.g. form.my-search). Per-form pre/post submit + AJAX hooks for custom front-end behavior.

Code lives under features/<name>/. Prefer a search-only key on the front; the client factory supports admin vs search.

Premium plugins

The free plugin is the search engine. Indexing, federated search, hybrid, analytics, and the scry_ms_* hooks stay in core. Premium add-ons sit on top when you want a ready-made UI for building Meilisearch search interfaces, without replacing your theme’s results templates. Facets in particular are how a large catalog becomes browsable, not just searchable.

Browse the catalog at scrywp.com/premium-plugins, and try the live demo of the free plugin plus both upgrades at demo.scrywp.com/search-demo. Two upgrades in particular:

  • Scry Search Facets – shortcode-driven facet UI (taxonomies, date ranges, and more) that turns visitor choices into Meilisearch filters on the same search path core already owns.
  • Scry Search Ajax – ajax search UI on top of the base window.scrySearch / submitAjax() runtime, so results can update without a full page reload.

Same connection, same indexes, same hooks. Install them from Scry Search Premium Upgrades when you are ready. Skip them when a custom front end, or the built-in autosuggest, is enough.

Managed hosting (ScryWP)

Self-hosting is first-class. Paste any Meilisearch URL and keys into Connection Settings — Docker, bare metal, a VPS, or local dev all work the same way. Pick post types, index, ship. A large catalog doesn’t change that path. It just means the engine has more documents to hold, which is what Meilisearch is for.

When you’d rather not run the search engine itself, ScryWP is managed hosting built for WordPress. On a big site, the index is large enough that “who patches Meilisearch” stops being a theoretical question. What you get upfront:

  • Engine upkeep — Meilisearch stays current; you’re not tracking release notes or patching prod yourself.
  • Monitoring & ops — health and capacity on the hosting side, so search failures aren’t a surprise SSH session.
  • Same plugin, same hooks — identical integration. No forked workflow; federation, hybrid, analytics, and scry_ms_* hooks behave the same as self-host.

That is the managed value: less infrastructure for you to operate, not a different product. Choose ScryWP when ops time or handoff complexity is not where you want to spend the budget. Choose self-host or local when you need full control, a compliance boundary, or an offline sandbox.

Hosting options

  1. ScryWP — managed: patched engine, monitoring, ops handled for you
  2. Self-hosted — your infrastructure, full control
  3. Local (dev) — same plugin path, offline or sandbox

Paste URL + keys, pick post types, index. Done.

Fits what you already have

  • Your theme’s search.php / results markup — unchanged
  • searchform.php, core search block/widget, page-builder search boxes
  • WooCommerce products
  • Custom post types + meta
  • Headless / custom front via WP_Query or REST if you build one

Get Managed Hosting from ScryWP

Don’t want to run Meilisearch yourself? ScryWP Search runs the engine for you — kept patched, monitored, and maintained — so search isn’t another server to babysit. Self-hosting and local dev stay fully supported. Details are under Managed hosting (ScryWP) below.

Requirements

  • WordPress 5.2 or higher
  • PHP 8.1 or higher
  • A Meilisearch instance (ScryWP or self-hosted)

Support

Hooks/docs: DOCS.md or GitHub. Issues and questions: same repo or JG Web Development.