let debounceTimer; searchInput.addEventListener('input', (e) => clearTimeout(debounceTimer); debounceTimer = setTimeout(() => fetch(`/wp-json/mytheme/v1/search?s=$encodeURIComponent(e.target.value)`) .then(res => res.json()) .then(renderResults); , 300); ); | Site Type | Recommended Plugin | Reason | |-----------|-------------------|--------| | Small blog (<1k posts) | Ivory Search (free) | Simple, zero config | | Medium blog / news | Relevanssi Premium | Best for text relevance | | WooCommerce store | Fibosearch (free or pro) | Blazing fast, respects stock | | Large custom site (20k+ posts, many fields) | SearchWP + Live Search | Indexes everything, highly tunable | | Budget, lots of custom post types | Ajax Search Pro (one-time $39) | One-time payment, many layouts |
| Risk | Example | Mitigation | |------|---------|-------------| | Heavy queries (DoS) | s=aaaaaaaa... (100 chars) | Limit query length to 50 chars | | SQL injection | s=' OR 1=1 | Parameterized queries (WP core does this) | | Data leakage | Searching draft posts | Check current_user_can('read_post') | | XSS | Result contains <script> | Escape output with esc_html() | wordpress search plugin ajax
Fibosearch (free) – faster, better for WooCommerce, but custom fields require paid version. Best Premium AJAX Search Plugin SearchWP + Live Search add-on – most flexible, best for custom fields, supports PDFs, comments, custom tables. Starts at $99/year. let debounceTimer; searchInput
// Format and return JSON return array_map(function($post) return [ 'title' => get_the_title($post), 'url' => get_permalink($post), 'excerpt' => wp_trim_words($post->post_excerpt, 20) ]; , $query->posts); Starts at $99/year