{"id":261956,"date":"2026-03-04T17:06:18","date_gmt":"2026-03-04T17:06:18","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/scrywp-search\/"},"modified":"2026-09-04T13:17:51","modified_gmt":"2026-09-04T13:17:51","slug":"scry-search","status":"publish","type":"plugin","link":"https:\/\/me.wordpress.org\/plugins\/scry-search\/","author":21037131,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.6.0","stable_tag":"1.6.0","tested":"7.1","requires":"5.2","requires_php":"8.1","requires_plugins":null,"header_name":"Scry Search: Meilisearch for WordPress","header_author":"ScryWP","header_description":"A powerful semantic search plugin, powered by Meilisearch.","assets_banners_color":"","last_updated":"2026-09-04 13:17:51","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/scrywp.com","header_author_uri":"https:\/\/scrywp.com","rating":5,"author_block_rating":0,"active_installs":30,"downloads":1583,"num_ratings":3,"support_threads":3,"support_threads_resolved":2,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"jtgraham38","date":"2026-03-09 21:10:44","revision":3478547},"1.0.1":{"tag":"1.0.1","author":"jtgraham38","date":"2026-03-09 21:10:44","revision":3478547},"1.0.2":{"tag":"1.0.2","author":"jtgraham38","date":"2026-04-02 18:39:35","revision":3497742},"1.1.0":{"tag":"1.1.0","author":"jtgraham38","date":"2026-05-02 19:38:40","revision":3521097},"1.1.1":{"tag":"1.1.1","author":"jtgraham38","date":"2026-05-08 15:06:52","revision":3526660},"1.1.2":{"tag":"1.1.2","author":"jtgraham38","date":"2026-06-10 18:54:25","revision":3567966},"1.2.0":{"tag":"1.2.0","author":"jtgraham38","date":"2026-06-10 18:54:25","revision":3567966},"1.2.1":{"tag":"1.2.1","author":"jtgraham38","date":"2026-06-19 20:03:30","revision":3579173},"1.3.0":{"tag":"1.3.0","author":"jtgraham38","date":"2026-08-06 19:43:46","revision":3637003},"1.4.0":{"tag":"1.4.0","author":"jtgraham38","date":"2026-08-07 18:43:08","revision":3638233},"1.5.0":{"tag":"1.5.0","author":"jtgraham38","date":"2026-08-19 18:57:19","revision":3655199},"1.5.1":{"tag":"1.5.1","author":"jtgraham38","date":"2026-08-28 21:21:32","revision":3670935},"1.5.2":{"tag":"1.5.2","author":"jtgraham38","date":"2026-09-02 23:25:47","revision":3678785},"1.6.0":{"tag":"1.6.0","author":"jtgraham38","date":"2026-09-04 13:17:51","revision":3681272}},"upgrade_notice":{"1.6.0":"<p>Lifecycle cleanup on deactivate\/uninstall, password-protected post skip, pagination fix, CSV formula hardening, Recent Searches column hooks, autosuggest localization, and task pane fixes. See DOCS.md.<\/p>","1.5.2":"<p>Bug fixes and added a new hook.<\/p>","1.5.1":"<p>Search forms are discovered by CSS selector; extend the list with <code>scry_ms_window_localized<\/code>, and optionally limit autosuggest by form class. See DOCS.md.<\/p>","1.5.0":"<p>Hybrid\/semantic search and embedder management are now built into Index Settings, plus draggable searchable-field ordering and analytics for hybrid queries. See DOCS.md.<\/p>","1.4.0":"<p>Tabbed Index Settings: filterable fields, custom ranking rules, dictionary, typo tolerance, raw JSON viewers, plus batched bulk indexing and new <code>scry_ms_*<\/code> hooks. See DOCS.md.<\/p>","1.3.0":"<p>More developer hooks (indexing\/search gates, client factory, autosuggest results, admin tabs), optional highlighting, autosuggest thumbnails, analytics metadata, Hybrid listing, indexing fix for embedder setups. See DOCS.md.<\/p>","1.2.1":"<p>Upgrades page updates; task pane fix for multi-tenant Meilisearch.<\/p>","1.2.0":"<p>Logs screen and expanded hooks \/ <code>window.scrySearch<\/code> (see DOCS.md).<\/p>","1.1.2":"<p>Analytics CSV export and retention cleanup.<\/p>","1.0.3":"<p>Optional AJAX autosuggest under Search Settings.<\/p>","1.0.0":"<p>Initial release.<\/p>"},"ratings":{"1":0,"2":0,"3":0,"4":0,"5":3},"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3474753,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3474753,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0","1.0.1","1.0.2","1.1.0","1.1.1","1.1.2","1.2.0","1.2.1","1.3.0","1.4.0","1.5.0","1.5.1","1.5.2","1.6.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3670935,"resolution":"1","location":"assets","locale":"","width":307,"height":486},"screenshot-10.png":{"filename":"screenshot-10.png","revision":3670935,"resolution":"10","location":"assets","locale":"","width":595,"height":634},"screenshot-11.png":{"filename":"screenshot-11.png","revision":3670935,"resolution":"11","location":"assets","locale":"","width":592,"height":634},"screenshot-12.png":{"filename":"screenshot-12.png","revision":3670935,"resolution":"12","location":"assets","locale":"","width":954,"height":881},"screenshot-13.png":{"filename":"screenshot-13.png","revision":3670935,"resolution":"13","location":"assets","locale":"","width":954,"height":879},"screenshot-14.png":{"filename":"screenshot-14.png","revision":3670935,"resolution":"14","location":"assets","locale":"","width":917,"height":887},"screenshot-15.png":{"filename":"screenshot-15.png","revision":3670935,"resolution":"15","location":"assets","locale":"","width":490,"height":904},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3670935,"resolution":"2","location":"assets","locale":"","width":961,"height":878},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3670935,"resolution":"3","location":"assets","locale":"","width":958,"height":867},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3670935,"resolution":"4","location":"assets","locale":"","width":592,"height":634},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3670935,"resolution":"5","location":"assets","locale":"","width":593,"height":637},"screenshot-6.png":{"filename":"screenshot-6.png","revision":3670935,"resolution":"6","location":"assets","locale":"","width":595,"height":636},"screenshot-7.png":{"filename":"screenshot-7.png","revision":3670935,"resolution":"7","location":"assets","locale":"","width":592,"height":637},"screenshot-8.png":{"filename":"screenshot-8.png","revision":3670935,"resolution":"8","location":"assets","locale":"","width":591,"height":633},"screenshot-9.png":{"filename":"screenshot-9.png","revision":3670935,"resolution":"9","location":"assets","locale":"","width":590,"height":631}},"screenshots":{"1":"Index Settings Dashboard - Manage post type indexes, view document counts, and trigger indexing operations","2":"Index Configuration Modal - Tabbed settings for ranking rules, searchable\/filterable fields, synonyms, stop words, dictionary, typo tolerance, and hybrid search embedders","3":"Connection Settings - Configure Meilisearch URL and API keys with connection testing","4":"Search Settings - Configure post type search weights for federated search, enable AJAX autosuggest, and set the class selector for which forms receive predictive search","5":"Task Drawer - Monitor Meilisearch tasks with status, timing, and error details","6":"Live Search Preview - Test search queries directly from the admin panel","7":"Search Analytics - Dashboard, privacy\/retention settings, CSV export of analytics data"}},"plugin_section":[],"plugin_tags":[2275,274822,4073,230825,944],"plugin_category":[45],"plugin_contributors":[222622],"plugin_business_model":[],"class_list":["post-261956","plugin","type-plugin","status-publish","hentry","plugin_tags-developer","plugin_tags-extendable","plugin_tags-hooks","plugin_tags-meilisearch","plugin_tags-search","plugin_category-ecommerce","plugin_contributors-jtgraham38","plugin_committers-jtgraham38"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/scry-search\/assets\/icon-128x128.png?rev=3474753","icon_2x":"https:\/\/ps.w.org\/scry-search\/assets\/icon-256x256.png?rev=3474753","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/scry-search\/assets\/screenshot-1.png?rev=3670935","caption":"Index Settings Dashboard - Manage post type indexes, view document counts, and trigger indexing operations"},{"src":"https:\/\/ps.w.org\/scry-search\/assets\/screenshot-2.png?rev=3670935","caption":"Index Configuration Modal - Tabbed settings for ranking rules, searchable\/filterable fields, synonyms, stop words, dictionary, typo tolerance, and hybrid search embedders"},{"src":"https:\/\/ps.w.org\/scry-search\/assets\/screenshot-3.png?rev=3670935","caption":"Connection Settings - Configure Meilisearch URL and API keys with connection testing"},{"src":"https:\/\/ps.w.org\/scry-search\/assets\/screenshot-4.png?rev=3670935","caption":"Search Settings - Configure post type search weights for federated search, enable AJAX autosuggest, and set the class selector for which forms receive predictive search"},{"src":"https:\/\/ps.w.org\/scry-search\/assets\/screenshot-5.png?rev=3670935","caption":"Task Drawer - Monitor Meilisearch tasks with status, timing, and error details"},{"src":"https:\/\/ps.w.org\/scry-search\/assets\/screenshot-6.png?rev=3670935","caption":"Live Search Preview - Test search queries directly from the admin panel"},{"src":"https:\/\/ps.w.org\/scry-search\/assets\/screenshot-7.png?rev=3670935","caption":"Search Analytics - Dashboard, privacy\/retention settings, CSV export of analytics data"},{"src":"https:\/\/ps.w.org\/scry-search\/assets\/screenshot-8.png?rev=3670935","caption":""},{"src":"https:\/\/ps.w.org\/scry-search\/assets\/screenshot-9.png?rev=3670935","caption":""},{"src":"https:\/\/ps.w.org\/scry-search\/assets\/screenshot-10.png?rev=3670935","caption":""},{"src":"https:\/\/ps.w.org\/scry-search\/assets\/screenshot-11.png?rev=3670935","caption":""},{"src":"https:\/\/ps.w.org\/scry-search\/assets\/screenshot-12.png?rev=3670935","caption":""},{"src":"https:\/\/ps.w.org\/scry-search\/assets\/screenshot-13.png?rev=3670935","caption":""},{"src":"https:\/\/ps.w.org\/scry-search\/assets\/screenshot-14.png?rev=3670935","caption":""},{"src":"https:\/\/ps.w.org\/scry-search\/assets\/screenshot-15.png?rev=3670935","caption":""}],"raw_content":"<!--section=description-->\n<p>Scry Search wires Meilisearch into WordPress the way you'd want it on a client project: fast keyword search, optional AI\/semantic (hybrid) search, and a big extension surface \u2014 without ripping out your theme.<\/p>\n\n<p><strong>Docs (start here):<\/strong> <a href=\"https:\/\/github.com\/jtgraham38\/ScryWP-Search\/blob\/main\/DOCS.md\">DOCS.md on GitHub<\/a> \u2014 every filter\/action, args, return values, when it fires, plus the <code>window.scrySearch<\/code> JS API. Same file ships in the plugin zip.<\/p>\n\n<p>You get over <strong>40 PHP hooks<\/strong> (<code>scry_ms_*<\/code>) covering indexing, documents, index settings, federated search, autosuggest, analytics, logs, and the front-end runtime. Call sites are marked in source. 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.<\/p>\n\n<h4>No theme changes. Not glued to a results UI.<\/h4>\n\n<p>This is the important bit:<\/p>\n\n<ul>\n<li>We do <strong>not<\/strong> replace your search results template. <code>search.php<\/code> (or whatever your theme \/ builder uses) still renders the results.<\/li>\n<li>We do <strong>not<\/strong> require a shortcode, block, or widget. Autosuggest and highlighting are optional and off unless you turn them on.<\/li>\n<li>Existing search forms keep working. Gutenberg Search block, classic <code>searchform.php<\/code>, Elementor\/Divi\/Beaver search widgets \u2014 they still POST to WordPress; we intercept the query.<\/li>\n<\/ul>\n\n<p>Admin-side tuning is a different story: ranking, searchable\/filterable fields, synonyms, typo tolerance, hybrid embedders, federated weights, etc. are all in wp-admin (see below). You\u2019re not stuck editing Meilisearch JSON by hand \u2014 you\u2019re just not locked into a plugin-owned results page.<\/p>\n\n<p>Under the hood we hook <code>posts_pre_query<\/code>, run the search in Meilisearch, and hand WordPress normal <code>WP_Post<\/code> objects. Same loop, same template tags, same pagination assumptions your theme already has.<\/p>\n\n<p>Need native WP search for one query? <code>scry_ms_should_search<\/code>.<\/p>\n\n<h4>Built-in semantic \/ hybrid search<\/h4>\n\n<p>Keyword search is the baseline. Hybrid search is built into the core plugin (not a separate SKU): Meilisearch blends full-text ranking with vector similarity so \"fuzzy intent\" queries still hit the right posts\/products.<\/p>\n\n<p>Per index, under <strong>Index Settings \u2192 Configure Index \u2192 Hybrid Search<\/strong>:<\/p>\n\n<ul>\n<li>Add embedders (OpenAI, Hugging Face, Ollama, user-provided vectors, other Meilisearch-supported sources)<\/li>\n<li>Pick which embedder to use and the semantic vs keyword ratio<\/li>\n<li>Enable hybrid per post type \u2014 products can differ from posts<\/li>\n<\/ul>\n\n<p>Same <code>WP_Query<\/code> path as keyword search. No second endpoint, no alternate results page. Reindex after embedder changes so vectors exist. Analytics can record hybrid usage in <code>search_metadata<\/code>.<\/p>\n\n<h4>What you configure in wp-admin<\/h4>\n\n<p>Most of Meilisearch\u2019s knobs are in WordPress \u2014 you don\u2019t need to curl the instance for day-to-day tuning.<\/p>\n\n<p><strong>Connection<\/strong> \u2014 URL, admin key, optional search-only key, connection test.<\/p>\n\n<p><strong>Index Settings<\/strong> (tabbed dialog per post type):<\/p>\n\n<ul>\n<li>Searchable fields \u2014 titles, content, excerpts, taxonomies, author, custom meta (ACF, Meta Box, etc.); drag to set relevancy order<\/li>\n<li>Filterable fields \u2014 post type\/status\/author, <code>post_date_unix<\/code>, taxonomy IDs (<code>taxonomies.&lt;name&gt;.id<\/code>), and more for facets \/ advanced filters<\/li>\n<li>Ranking rules \u2014 reorder words \/ typo \/ proximity \/ attribute \/ sort \/ exactness; add custom <code>attribute:asc<\/code> \/ <code>attribute:desc<\/code><\/li>\n<li>Synonyms, stop words, dictionary \u2014 nicknames, brand aliases, noise terms, multi-word tokens<\/li>\n<li>Typo tolerance \u2014 enable\/disable, min word sizes, disable on numbers \/ words \/ attributes<\/li>\n<li>Hybrid Search \u2014 embedders and semantic ratio (see above)<\/li>\n<li>View Raw JSON on each group when something looks off<\/li>\n<li>Bulk index \/ wipe, plus a live search preview before you ship ranking changes<\/li>\n<\/ul>\n\n<p><strong>Search Settings<\/strong> \u2014 federated post-type weights (e.g. products above blog posts), optional AJAX autosuggest (with optional form class targeting), optional matched-term highlighting (<code>.scry-ms-highlight<\/code>).<\/p>\n\n<p><strong>Ops<\/strong> \u2014 task pane, Logs, Search Analytics (see <strong>For developers<\/strong>).<\/p>\n\n<p>You can go live from these screens alone. Hooks kick in when a project needs something the UI doesn\u2019t cover.<\/p>\n\n<h4>Autosuggest + highlighting (optional front-end extras)<\/h4>\n\n<p>These are the only front-end UI pieces the plugin ships, and both are off by default. Your theme\u2019s results page stays yours either way.<\/p>\n\n<p><strong>Autosuggest<\/strong> \u2014 Search Settings toggle. The front-end runtime finds forms via CSS selectors (defaults: <code>#adminbarsearch<\/code>, <code>form[role=\"search\"]<\/code>, 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 <code>scry_ms_window_localized<\/code> \u2014 details in DOCS.md. Shape data with <code>scry_ms_autosuggest_results<\/code> or markup with <code>scry_ms_autosuggest_results_rendered<\/code>.<\/p>\n\n<p><strong>Highlighting<\/strong> \u2014 optional matched-term markup in results \/ autosuggest (class <code>.scry-ms-highlight<\/code>). Style it in your theme; we don\u2019t force a look.<\/p>\n\n<h4>Indexes and federation<\/h4>\n\n<p>Each registered post type can get its own Meilisearch index (posts, pages, <code>product<\/code>, CPTs). Federated multi-search merges them with your Search Settings weights \u2014 not a home-rolled PHP merge.<\/p>\n\n<p>WooCommerce: select <code>product<\/code>, pick product fields\/meta, set weights if you also search posts\/pages. Catalog search upgrades; theme and checkout stay as they are.<\/p>\n\n<h4>Ops: indexing<\/h4>\n\n<ul>\n<li>Auto-index on save; remove on trash\/delete; re-index on untrash. Bulk index \/ wipe from Index Settings.<\/li>\n<li>Task pane, Logs, and Search Analytics are covered under <strong>For developers<\/strong> below (they\u2019re useful for site owners too, but they\u2019re built as day-to-day ops tooling).<\/li>\n<\/ul>\n\n<h4>For developers<\/h4>\n\n<p><strong>Full hook reference + JS API:<\/strong> <a href=\"https:\/\/github.com\/jtgraham38\/ScryWP-Search\/blob\/main\/DOCS.md\">DOCS.md on GitHub<\/a><\/p>\n\n<p><strong>45 PHP hooks<\/strong> documented there (filters + actions). Names below; args\/returns\/timing in the docs. Call sites tagged <code>\/\/@HOOK: scry_ms_\u2026<\/code> in source.<\/p>\n\n<p><strong>Task pane<\/strong> \u2014 drawer on plugin admin screens for Meilisearch tasks on indexes this plugin owns: status, duration, errors, paginated history. Shared Meilisearch instances won\u2019t dump unrelated tasks. Useful when bulk indexing stalls or a settings update fails silently.<\/p>\n\n<p><strong>Error \/ debug logs<\/strong> \u2014 Scry Search \u2192 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 <code>scry_ms_log_message<\/code> if you need to divert or annotate lines.<\/p>\n\n<p><strong>Search analytics<\/strong> \u2014 Scry Search \u2192 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 <code>scry_ms_analytics_event_to_insert<\/code> (non-column keys go into <code>search_metadata<\/code>, including hybrid usage when enabled).<\/p>\n\n<p>Filters \u2014 indexing \/ documents:<\/p>\n\n<ul>\n<li><code>scry_ms_should_index<\/code>, <code>scry_ms_should_delete<\/code>, <code>scry_ms_index_prepare_document<\/code><\/li>\n<li><code>scry_ms_index_names<\/code>, <code>scry_ms_index_searchable_attributes<\/code>, <code>scry_ms_index_filterable_attributes<\/code>, <code>scry_ms_index_filterable_fields<\/code><\/li>\n<li><code>scry_ms_index_typo_tolerance<\/code>, <code>scry_ms_index_ranking_rules<\/code>, <code>scry_ms_index_fields<\/code>, <code>scry_ms_index_meta_keys<\/code><\/li>\n<li><code>scry_ms_bulk_index_query_args<\/code>, <code>scry_ms_bulk_index_batch_size<\/code><\/li>\n<\/ul>\n\n<p>Filters \u2014 settings:<\/p>\n\n<ul>\n<li><code>scry_ms_index_settings_ajax<\/code>, <code>scry_ms_index_settings_backup<\/code><\/li>\n<li><code>scry_ms_index_ranking_rules_before_update<\/code>, <code>scry_ms_index_searchable_attributes_before_update<\/code><\/li>\n<li><code>scry_ms_index_synonyms_before_update<\/code>, <code>scry_ms_index_stop_words_before_update<\/code><\/li>\n<li><code>scry_ms_index_filterable_attributes_before_update<\/code>, <code>scry_ms_index_dictionary_before_update<\/code>, <code>scry_ms_index_typo_tolerance_before_update<\/code><\/li>\n<\/ul>\n\n<p>Filters \u2014 search \/ client:<\/p>\n\n<ul>\n<li><code>scry_ms_should_search<\/code>, <code>scry_ms_meilisearch_client<\/code><\/li>\n<li><code>scry_ms_multi_search_index_names<\/code>, <code>scry_ms_multi_search_query_params<\/code>, <code>scry_ms_multi_search_query<\/code>, <code>scry_ms_multi_search_queries<\/code><\/li>\n<li><code>scry_ms_multi_search_federation<\/code>, <code>scry_ms_multi_search_raw_results<\/code>, <code>scry_ms_multi_search_final_results<\/code><\/li>\n<\/ul>\n\n<p>Filters \u2014 autosuggest \/ admin \/ analytics \/ logs \/ window:<\/p>\n\n<ul>\n<li><code>scry_ms_autosuggest_query<\/code>, <code>scry_ms_autosuggest_results<\/code>, <code>scry_ms_autosuggest_results_rendered<\/code>, <code>scry_ms_autosuggest_localized<\/code><\/li>\n<li><code>scry_ms_admin_pages<\/code>, <code>scry_ms_analytics_event_to_insert<\/code>, <code>scry_ms_analytics_recent_searches_columns<\/code>, <code>scry_ms_analytics_recent_searches_column<\/code>, <code>scry_ms_log_message<\/code>, <code>scry_ms_window_localized<\/code><\/li>\n<\/ul>\n\n<p>Actions:<\/p>\n\n<ul>\n<li><code>scry_ms_after_index_document<\/code>, <code>scry_ms_after_delete_document<\/code>, <code>scry_ms_after_bulk_index<\/code>, <code>scry_ms_after_create_index<\/code><\/li>\n<li><code>scry_ms_index_settings_restore<\/code>, <code>scry_ms_index_update_settings<\/code>, <code>scry_ms_index_settings_sections_ui<\/code><\/li>\n<\/ul>\n\n<p><strong>JS:<\/strong> <code>window.scrySearch<\/code> (handle <code>scry_ms_window-script<\/code>). Wait for <code>scrySearchReady<\/code>. Forms from <code>windowLocalized.searchFormSelectors<\/code>; filter <code>scry_ms_window_localized<\/code> to add selectors (e.g. <code>form.my-search<\/code>). Per-form pre\/post submit + AJAX hooks for custom front-end behavior.<\/p>\n\n<p>Code lives under <code>features\/&lt;name&gt;\/<\/code>. Prefer a search-only key on the front; the client factory supports admin vs search.<\/p>\n\n<h4>Managed hosting (ScryWP)<\/h4>\n\n<p><strong>Self-hosting is first-class.<\/strong> Paste any Meilisearch URL and keys into Connection Settings \u2014 Docker, bare metal, VPS, or local dev all work the same way. Pick post types, index, ship.<\/p>\n\n<p>When you'd rather not run the search engine itself, <a href=\"https:\/\/scrywp.com\">ScryWP<\/a> is managed hosting built for WordPress. What you get upfront:<\/p>\n\n<ul>\n<li><strong>Engine upkeep<\/strong> \u2014 Meilisearch stays current; you're not tracking release notes or patching prod yourself.<\/li>\n<li><strong>Monitoring &amp; ops<\/strong> \u2014 health and capacity on the hosting side, so search failures aren't a surprise SSH session.<\/li>\n<li><strong>Same plugin, same hooks<\/strong> \u2014 identical integration. No forked workflow; federation, hybrid, analytics, and <code>scry_ms_*<\/code> hooks behave the same as self-host.<\/li>\n<\/ul>\n\n<p>That's the managed value: less infrastructure to operate, not a different product. Choose ScryWP when ops time or handoff complexity isn't where you want to spend budget. Choose self-host or local when you need full control, compliance boundaries, or an offline sandbox.<\/p>\n\n<h4>Hosting options<\/h4>\n\n<ol>\n<li><strong><a href=\"https:\/\/scrywp.com\">ScryWP<\/a><\/strong> \u2014 managed: patched engine, monitoring, ops handled for you<\/li>\n<li><strong>Self-hosted<\/strong> \u2014 your infrastructure, full control<\/li>\n<li><strong>Local (dev)<\/strong> \u2014 same plugin path, offline or sandbox<\/li>\n<\/ol>\n\n<p>Paste URL + keys, pick post types, index. Done.<\/p>\n\n<h4>Fits what you already have<\/h4>\n\n<ul>\n<li>Your theme's <code>search.php<\/code> \/ results markup \u2014 unchanged<\/li>\n<li><code>searchform.php<\/code>, core search block\/widget, page-builder search boxes<\/li>\n<li>WooCommerce products<\/li>\n<li>Custom post types + meta<\/li>\n<li>Headless \/ custom front via <code>WP_Query<\/code> or REST if you build one<\/li>\n<\/ul>\n\n<h3>Get Managed Hosting from ScryWP<\/h3>\n\n<p>Don't want to operate Meilisearch yourself? <a href=\"https:\/\/scrywp.com\">ScryWP Search<\/a> runs the engine for you \u2014 kept patched, monitored, and maintained \u2014 so search isn't another server to babysit. Self-hosting and local dev stay fully supported; see <strong>Managed hosting (ScryWP)<\/strong> below.<\/p>\n\n<h3>Requirements<\/h3>\n\n<ul>\n<li>WordPress 5.2 or higher<\/li>\n<li>PHP 8.1 or higher<\/li>\n<li>A Meilisearch instance (ScryWP or self-hosted)<\/li>\n<\/ul>\n\n<h3>Support<\/h3>\n\n<p>Hooks\/docs: DOCS.md or <a href=\"https:\/\/github.com\/jtgraham38\/ScryWP-Search\">GitHub<\/a>. Issues and questions: same repo or <a href=\"https:\/\/jacob-t-graham.com\">JG Web Development<\/a>.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Have a Meilisearch instance running \u2014 self-hosted, local, or <a href=\"https:\/\/scrywp.com\">ScryWP<\/a> managed (see <strong>Managed hosting (ScryWP)<\/strong> above).<\/li>\n<li>Install and activate the plugin (upload to <code>wp-content\/plugins\/<\/code> or via Plugins \u2192 Add New).<\/li>\n<li>Scry Search \u2192 Connection Settings: URL, admin key, optional search key; test connection.<\/li>\n<li>Scry Search \u2192 Index Settings: choose post types, save, Index Posts for each.<\/li>\n<li>WordPress search now uses Meilisearch. No theme changes required.<\/li>\n<li>Optional: enable autosuggest or highlighting under Search Settings.<\/li>\n<li>Optional: open DOCS.md and add your first <code>add_filter( 'scry_ms_\u2026' )<\/code>.<\/li>\n<\/ol>\n\n<p>You can complete the whole flow from wp-admin without custom code. Hooks are there when you need them.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"what%20happens%20when%20i%20deactivate%20or%20uninstall%3F\"><h3>What happens when I deactivate or uninstall?<\/h3><\/dt>\n<dd><p>Deactivating clears the plugin's daily cron jobs (analytics and log cleanup) so they stop running while the plugin is inactive. Your settings, API keys, custom tables, and Meilisearch indexes are left in place \u2014 reactivating restores normal operation and re-schedules cron.<\/p>\n\n<p>Deleting the plugin (uninstall) removes the two custom database tables (<code>scry_ms_search_analytics<\/code>, <code>scry_ms_logs<\/code>), all <code>scry_ms_*<\/code> options (connection keys, embedder secrets, index backups, etc.), and any remaining scheduled cron events. It does not delete indexes or documents on your Meilisearch server.<\/p><\/dd>\n<dt id=\"will%20password-protected%20posts%20be%20indexed%3F\"><h3>Will password-protected posts be indexed?<\/h3><\/dt>\n<dd><p>No for live saves \u2014 published posts with a password are skipped before indexing. Use <code>scry_ms_should_index<\/code> on bulk reindex (or always) if you need the same rule there. Already-indexed protected posts stay in Meilisearch until you reindex\/wipe.<\/p><\/dd>\n<dt id=\"what%20makes%20this%20developer-friendly%3F\"><h3>What makes this developer-friendly?<\/h3><\/dt>\n<dd><p>45 documented <code>scry_ms_*<\/code> hooks, call sites marked in source, shared client filter, and a real docs file \u2014 not a marketing PDF. Plus the tooling you\u2019d actually use on a site: task pane for Meilisearch jobs, error\/debug logs, and search analytics (dashboard + CSV). Start here: <a href=\"https:\/\/github.com\/jtgraham38\/ScryWP-Search\/blob\/main\/DOCS.md\">DOCS.md<\/a>. Optional <code>window.scrySearch<\/code> if you need front-end glue. No forced search results UI.<\/p><\/dd>\n<dt id=\"can%20non-developers%20use%20it%3F\"><h3>Can non-developers use it?<\/h3><\/dt>\n<dd><p>Yes. Connect Meilisearch, pick post types, index, tune ranking\/synonyms\/weights\/hybrid\/autosuggest from wp-admin. Bring a developer when you need behavior the screens don't cover.<\/p><\/dd>\n<dt id=\"do%20i%20need%20semantic%20%2F%20ai%20search%3F\"><h3>Do I need semantic \/ AI search?<\/h3><\/dt>\n<dd><p>Optional. Keyword search works without it. Hybrid is in core when you want vector similarity alongside full-text \u2014 configure embedders per index, reindex, same results templates.<\/p><\/dd>\n<dt id=\"do%20i%20have%20to%20use%20a%20frontend%20ui%20from%20the%20plugin%3F\"><h3>Do I have to use a frontend UI from the plugin?<\/h3><\/dt>\n<dd><p>No. We don\u2019t own your results page \u2014 your theme (or builder) still displays posts from <code>WP_Query<\/code>. Ranking, fields, synonyms, typo tolerance, hybrid, weights, etc. are configured in wp-admin. Autosuggest and highlighting are the optional front-end extras; leave them off and you\u2019re indexing + query routing only.<\/p><\/dd>\n<dt id=\"do%20i%20need%20to%20change%20my%20theme%3F\"><h3>Do I need to change my theme?<\/h3><\/dt>\n<dd><p>No. Forms and <code>search.php<\/code> (or equivalent) keep working. We swap the query engine, not the markup. Page-builder search boxes that hit WordPress search work the same way.<\/p><\/dd>\n<dt id=\"what%20is%20meilisearch%3F\"><h3>What is Meilisearch?<\/h3><\/dt>\n<dd><p>Open-source, typo-tolerant search engine: <a href=\"https:\/\/www.meilisearch.com\/\">meilisearch.com<\/a>. This plugin assumes you already chose it (or will via ScryWP); we focus on the WordPress integration.<\/p><\/dd>\n<dt id=\"scrywp%20or%20self-host%3F\"><h3>ScryWP or self-host?<\/h3><\/dt>\n<dd><p><strong>Self-host<\/strong> (or local dev) when you want full control, compliance boundaries, or you already run Meilisearch elsewhere. <strong>ScryWP<\/strong> when you'd rather not operate the engine \u2014 Meilisearch kept patched and monitored on the hosting side, same plugin integration (paste URL + keys like any instance). Federation, hybrid, and hooks work identically either way.<\/p><\/dd>\n<dt id=\"custom%20post%20types%20and%20meta%3F\"><h3>Custom post types and meta?<\/h3><\/dt>\n<dd><p>Yes. Each selected post type gets its own index. Meta shows up in searchable fields; tweak via admin or <code>scry_ms_index_fields<\/code> \/ <code>scry_ms_index_meta_keys<\/code> \/ <code>scry_ms_index_prepare_document<\/code>.<\/p><\/dd>\n<dt id=\"how%20does%20federated%20search%20work%3F\"><h3>How does federated search work?<\/h3><\/dt>\n<dd><p>Meilisearch multi-search with federation across your indexes, using the weights you set in Search Settings. Adjust the request with <code>scry_ms_multi_search_*<\/code>.<\/p><\/dd>\n<dt id=\"will%20this%20work%20with%20woocommerce%3F\"><h3>Will this work with WooCommerce?<\/h3><\/dt>\n<dd><p>Yes. Index <code>product<\/code>, choose fields\/meta, set weights if you federate with other types. Theme and checkout stay unchanged.<\/p><\/dd>\n<dt id=\"synonyms%2C%20stopwords%2C%20dictionary%2C%20and%20typo%20tolerance%3F\"><h3>Synonyms, stopwords, dictionary, and typo tolerance?<\/h3><\/dt>\n<dd><p>Yes \u2014 per index in the Index Settings dialog (dedicated tabs), no Meilisearch config files required. Also filterable from code when you need that.<\/p><\/dd>\n<dt id=\"can%20i%20configure%20filterable%20fields%20from%20wordpress%3F\"><h3>Can I configure filterable fields from WordPress?<\/h3><\/dt>\n<dd><p>Yes. The Filterable Fields tab lets you pick core fields, taxonomy IDs, and related attributes. Defaults and the field tree are adjustable with <code>scry_ms_index_filterable_attributes<\/code> \/ <code>scry_ms_index_filterable_fields<\/code>.<\/p><\/dd>\n<dt id=\"how%20do%20i%20customize%20with%20code%3F\"><h3>How do I customize with code?<\/h3><\/dt>\n<dd><p>Hook list is under <strong>For developers<\/strong> above. Common starters: <code>scry_ms_should_index<\/code>, <code>scry_ms_index_prepare_document<\/code>, <code>scry_ms_meilisearch_client<\/code>, <code>scry_ms_autosuggest_results<\/code> \/ <code>scry_ms_autosuggest_results_rendered<\/code>, <code>scry_ms_admin_pages<\/code>. Full signatures: <a href=\"https:\/\/github.com\/jtgraham38\/ScryWP-Search\/blob\/main\/DOCS.md\">DOCS.md<\/a>.<\/p><\/dd>\n<dt id=\"javascript%20api%3F\"><h3>JavaScript API?<\/h3><\/dt>\n<dd><p>Optional. Wait for <code>scrySearchReady<\/code>, then <code>window.scrySearch<\/code> + per-form pre\/post (and AJAX) hooks. Skip it if you're not doing front-end work. Examples in DOCS.md.<\/p><\/dd>\n<dt id=\"how%20do%20i%20debug%20indexing%3F\"><h3>How do I debug indexing?<\/h3><\/dt>\n<dd><p>Task pane for Meilisearch tasks on managed indexes; Scry Search \u2192 Logs for plugin debug\/error lines (secrets redacted, retention available). See <strong>For developers<\/strong>.<\/p><\/dd>\n<dt id=\"can%20i%20export%20analytics%3F\"><h3>Can I export analytics?<\/h3><\/dt>\n<dd><p>Yes \u2014 Search Analytics includes CSV export, retention\/cleanup, privacy options, and <code>scry_ms_analytics_event_to_insert<\/code> for extra fields. Covered under <strong>For developers<\/strong>.<\/p><\/dd>\n<dt id=\"is%20it%20secure%3F\"><h3>Is it secure?<\/h3><\/dt>\n<dd><p>AJAX nonces, capability checks, sanitized\/escaped I\/O. Prefer a search-only API key for front-end paths; the client factory supports <code>admin<\/code> vs <code>search<\/code> keys.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.6.0<\/h4>\n\n<ul>\n<li>Plugin lifecycle: <code>register_deactivation_hook<\/code> clears daily analytics\/log cron events; <code>uninstall.php<\/code> drops custom tables and deletes all <code>scry_ms_*<\/code> options<\/li>\n<li>Password-protected posts are skipped on live indexing (built-in; still filterable via <code>scry_ms_should_index<\/code>)<\/li>\n<li>Federated search pagination keeps Meilisearch <code>estimatedTotalHits<\/code> for <code>found_posts<\/code> \/ <code>max_num_pages<\/code> (no longer overwritten by the current page size)<\/li>\n<li>Analytics CSV export sanitizes cells that start with <code>=<\/code>, <code>+<\/code>, <code>-<\/code>, <code>@<\/code>, tab, or CR to prevent spreadsheet formula injection<\/li>\n<li>Recent Searches table is extensible: <code>scry_ms_analytics_recent_searches_columns<\/code>, <code>scry_ms_analytics_recent_searches_column<\/code>, and optional <code>scry_ms_analytics_recent_searches_sortable_columns<\/code>; rows expose decoded <code>search_metadata<\/code><\/li>\n<li>Autosuggest: <code>scry_ms_autosuggest_localized<\/code> filter; remove hidden <code>return_type<\/code> input after AJAX so it does not leak into normal form submits<\/li>\n<li>Semantic search onboarding notice is dismissible (cookie); overview CTA \/ card action dashicons alignment polish<\/li>\n<li>Readme: stronger managed-hosting (ScryWP) copy while keeping self-host first-class<\/li>\n<li>DOCS.md \/ README updated for new hooks and lifecycle behavior<\/li>\n<li>Fixed bug loading tasks in the task pane<\/li>\n<\/ul>\n\n<h4>1.5.2<\/h4>\n\n<ul>\n<li>Fixed a bug with the updated indexing logic<\/li>\n<li>Enabled filtering of the localization of autosuggest script<\/li>\n<\/ul>\n\n<h4>1.5.1<\/h4>\n\n<ul>\n<li>Front-end form discovery via CSS selectors (<code>#adminbarsearch<\/code>, <code>form[role=\"search\"]<\/code> by default), including Gutenberg Search block forms<\/li>\n<li>Extend discovery selectors with <code>scry_ms_window_localized<\/code> (<code>searchFormSelectors<\/code>)<\/li>\n<li>Autosuggest class selector limits typeahead to discovered forms that carry a given CSS class on <code>&lt;form&gt;<\/code><\/li>\n<li>Window and autosuggest use separate localized JS objects (avoids config collisions)<\/li>\n<li>DOCS.md \/ README updated for form discovery and autosuggest targeting<\/li>\n<\/ul>\n\n<h4>1.5.0<\/h4>\n\n<ul>\n<li>Hybrid \/ semantic search in core \u2014 Hybrid Search tab per index with embedder add\/edit\/delete, semantic ratio, and federated search integration<\/li>\n<li>Embedder definitions backed up in WordPress and restored when an index is recreated; preserved when wiping\/reindexing<\/li>\n<li>Search analytics records hybrid usage in <code>search_metadata<\/code> (<code>scry_search_hybrid<\/code>) when hybrid is active<\/li>\n<li>Searchable fields: drag-and-drop reorder (saved as Meilisearch <code>searchableAttributes<\/code> order)<\/li>\n<li>Default searchable attribute order prioritizes title, excerpt, then content<\/li>\n<li>Index settings UI treats Meilisearch <code>[\"*\"]<\/code> searchable attributes as all fields selected<\/li>\n<li>DOCS.md \/ README updated<\/li>\n<\/ul>\n\n<h4>1.4.0<\/h4>\n\n<ul>\n<li>Tabbed Index Settings dialog covering ranking rules, searchable fields, filterable fields, synonyms, stop words, dictionary, and typo tolerance<\/li>\n<li>Filterable attributes managed in core \u2014 including post taxonomies (<code>taxonomies.&lt;name&gt;.id<\/code>) and <code>post_date_unix<\/code><\/li>\n<li>Custom ranking rules (<code>attribute:asc<\/code> \/ <code>attribute:desc<\/code>) with drag-and-drop ordering alongside built-in rules<\/li>\n<li>Dictionary and typo tolerance settings (enable\/disable, min word sizes, disable on numbers\/words\/attributes)<\/li>\n<li>View Raw JSON on each settings section for debugging<\/li>\n<li>Settings backup\/restore now includes filterable attributes, dictionary, and typo tolerance<\/li>\n<li>New hooks: <code>scry_ms_index_filterable_attributes<\/code>, <code>scry_ms_index_filterable_fields<\/code>, <code>scry_ms_index_filterable_attributes_before_update<\/code>, <code>scry_ms_index_dictionary_before_update<\/code>, <code>scry_ms_index_typo_tolerance<\/code>, <code>scry_ms_index_typo_tolerance_before_update<\/code>, <code>scry_ms_bulk_index_batch_size<\/code><\/li>\n<li>Bulk indexing processes posts in batches (memory-friendly; batch size filterable)<\/li>\n<li>Setup breadcrumb navigation on admin pages<\/li>\n<li>DOCS.md \/ README updated for the new index settings surface<\/li>\n<\/ul>\n\n<h4>1.3.0<\/h4>\n\n<ul>\n<li>New hooks: <code>should_index<\/code>, <code>should_delete<\/code>, <code>should_search<\/code>, <code>after_index_document<\/code>, <code>after_delete_document<\/code>, <code>after_bulk_index<\/code>, <code>index_names<\/code>, <code>index_searchable_attributes<\/code>, <code>bulk_index_query_args<\/code>, <code>meilisearch_client<\/code>, <code>autosuggest_results<\/code>, <code>autosuggest_results_rendered<\/code>, <code>admin_pages<\/code><\/li>\n<li>Customize how your site displays autosuggest results with the <code>autosuggest_results_rendered<\/code> hook<\/li>\n<li>Documents now include public taxonomy terms; <code>index_prepare_document<\/code> gets <code>WP_Post<\/code> as second arg<\/li>\n<li>Sync on <code>delete_post<\/code> and <code>untrash_post<\/code><\/li>\n<li>DOCS.md \/ README updated<\/li>\n<li>Optional matched-term highlighting in results and autosuggest (Search Settings; CSS class <code>.scry-ms-highlight<\/code>)<\/li>\n<li>Autosuggest can show featured-image thumbnails<\/li>\n<li>Analytics: extra keys on <code>scry_ms_analytics_event_to_insert<\/code> stored in <code>search_metadata<\/code> (CSV too)<\/li>\n<li>Premium Upgrades lists Scry Search Hybrid alongside Filters<\/li>\n<li>Index settings restored from WP only when an index is newly created (avoids re-PATCHing Meilisearch every admin load when embedders are set)<\/li>\n<\/ul>\n\n<h4>1.2.1<\/h4>\n\n<ul>\n<li>Task drawer only lists tasks for indexes this plugin manages<\/li>\n<li>Premium Upgrades page layout\/assets fix<\/li>\n<\/ul>\n\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>Logs screen (debug\/error, retention, secret redaction)<\/li>\n<li>More <code>scry_ms_*<\/code> hooks; documented in DOCS.md<\/li>\n<li><code>window.scrySearch<\/code> JS API<\/li>\n<li>Premium Upgrades admin page<\/li>\n<li>Federated search hit-count fix<\/li>\n<\/ul>\n\n<h4>1.1.2<\/h4>\n\n<ul>\n<li>Analytics CSV export, retention\/cleanup, privacy settings on Search Analytics<\/li>\n<\/ul>\n\n<h4>1.0.3<\/h4>\n\n<ul>\n<li>Optional AJAX autosuggest (Search Settings toggle + optional class selector)<\/li>\n<\/ul>\n\n<h4>1.0.2<\/h4>\n\n<ul>\n<li>Synonyms and stopwords from the WordPress admin<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>ScryWP-hosted Meilisearch support<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release: per-post-type indexes, federated search, ranking\/searchable fields, auto + bulk indexing, task drawer, live preview, drop-in WP search<\/li>\n<\/ul>","raw_excerpt":"Meilisearch for WordPress: keyword + built-in semantic\/hybrid search. Drop-in WP_Query, ~45 PHP hooks, no theme changes.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/261956","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=261956"}],"author":[{"embeddable":true,"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/jtgraham38"}],"wp:attachment":[{"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=261956"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=261956"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=261956"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=261956"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=261956"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/me.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=261956"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}