TL;DR: WordPress Search Interno in 30 Secondi
La ricerca interna di WordPress è il canale di conversione più sottovalutato nei siti che gestiamo per i clienti. Secondo i dati di Gigya, gli utenti che usano la ricerca interna convertono fino a 2-3 volte di più rispetto a quelli che navigano menu e categorie. Eppure, la ricerca nativa di WordPress è insicura, lenta e imprecisa: usa WP_Query con s come parametro, cerca solo in post_title e post_content, e ordina per data invece che per rilevanza.
In questa guida mostreremo come ottimizzare WordPress search interno per siti clienti: dal replacement del search nativo con endpoint REST API personalizzati all’integrazione con motori di ricerca esterni come Elasticsearch e MeiliSearch. Include codice production-ready, confronto tra plugin e strategie di automazione per agenzie.
Perché la Ricerca Nativa WordPress Non Basta
Il search nativo di WordPress ha limitazioni strutturali che rendono insufficiente per siti con più di 100 contenuti. Nella nostra esperienza gestendo 50+ siti clienti su AgencyPilot, abbiamo identificato questi problemi ricorrenti:
1. Algoritmo di Rilevanza Inesistente
WordPress esegue la ricerca tramite WP_Query con il parametro s. L’algoritmo di default:
- Cerca corrispondenze esatte in
post_titleepost_content - Non supporta ricerca fuzzy (errori di battitura, forme singolari/plurali)
- Ordina i risultati per data di pubblicazione, non per rilevanza
- Non pesa il titolo rispetto al contenuto (un match nel titolo vale quanto un match nel corpo)
Il risultato? Un utente cerca “hosting WordPress” e ottiene prima un articolo del 2021 marginale che menziona “hosting” una volta, poi una guida approfondita del 2025 con “hosting WordPress” nel titolo. Questo è inaccettabile per un sito professionale.
2. Performance su Database Grandi
La query di ricerca nativa esegue un LIKE '%term%' su wp_posts. Su tabelle con 10.000+ post, questo causa:
| Dimensione DB | Tempo query nativa | Tempo con indice fulltext | Tempo con Elasticsearch |
|---|---|---|---|
| 1.000 post | ~50ms | ~5ms | ~2ms |
| 10.000 post | ~300ms | ~20ms | ~3ms |
| 50.000 post | ~1.500ms | ~80ms | ~5ms |
| 100.000 post | ~4.000ms | ~150ms | ~5ms |
Dati misurati su ambiente di test con MySQL 8.0, server 4 vCPU 8GB RAM. Variabilità ±20%.
3. Nessun Supporto per Custom Fields
La ricerca nativa non cerca nei post_meta. Se un cliente ha un e-commerce con prodotti che hanno SKU, attributi o campi ACF personalizzati, la ricerca non li troverà mai. Per un’agenzia questo significa ticket di supporto continui: “il cliente non trova il prodotto XYZ”.
4. Sicurezza: Information Disclosure
La ricerca nativa di WordPress, senza filtri adeguati, può esporre:
- Contenuti in stato
draftoprivatein alcune configurazioni - Post types che non dovrebbero essere pubblicamente ricercabili (es. log interni, dati di debugging)
- Contenuti di siti multipli in installazioni multisite mal configurate
Le 5 Strategie per Ottimizzare WordPress Search Interno
Esistono cinque approcci progressivi per migliorare la ricerca interna, dal più semplice al più avanzato. La scelta dipende dal budget del cliente, dal volume di contenuti e dai requisiti di performance.
Strategia 1: Filtrare e Migliorare la Query Nativa (Costo: Basso)
Prima di installare plugin, è possibile migliorare significativamente la ricerca nativa con filtri WordPress. Questo approccio è ideale per siti con meno di 1.000 contenuti e budget limitato.
Esempio: Pesare il titolo nella ricerca
// functions.php — Dai più peso ai match nel titolo
add_filter('posts_search', function($search, $query) {
global $wpdb;
if (empty($search) || !is_search()) {
return $search;
}
$terms = $query->get('s');
$terms = esc_sql(sanitize_text_field($terms));
// Riscrive la clausola WHERE per dare priorità al titolo
$search = " AND (
({$wpdb->posts}.post_title LIKE '%{$terms}%')
OR ({$wpdb->posts}.post_content LIKE '%{$terms}%')
)";
// Ordina per rilevanza: prima i match nel titolo
add_filter('posts_orderby', function($orderby) {
global $wpdb;
return "CASE
WHEN {$wpdb->posts}.post_title LIKE '%" . $terms . "%' THEN 1
ELSE 2
END, {$wpdb->posts}.post_date DESC";
});
return $search;
}, 10, 2);
// Escludi post types non rilevanti dalla ricerca
add_filter('posts_search', function($search, $query) {
if (!is_search() || !$query->is_main_query()) {
return $search;
}
$query->set('post_type', array('post', 'page', 'product'));
$query->set('post_status', 'publish');
return $search;
}, 20, 2);
Esempio: Cercare nei custom field con JOIN
// Estendi la ricerca ai campi personalizzati
add_filter('posts_join', function($join, $query) {
global $wpdb;
if (!is_search() || !$query->is_main_query()) {
return $join;
}
$join .= " LEFT JOIN {$wpdb->postmeta} AS pm_search
ON {$wpdb->posts}.ID = pm_search.post_id
AND pm_search.meta_key IN ('_sku', 'product_specs', 'subtitle')";
return $join;
}, 10, 2);
add_filter('posts_where', function($where, $query) {
global $wpdb;
if (!is_search() || !$query->is_main_query()) {
return $where;
}
$terms = esc_sql(sanitize_text_field($query->get('s')));
$where .= " OR (pm_search.meta_value LIKE '%{$terms}%')";
return $where;
}, 10, 2);
// Evita duplicati con GROUP BY
add_filter('posts_groupby', function($groupby, $query) {
global $wpdb;
if (!is_search() || !$query->is_main_query()) {
return $groupby;
}
return "{$wpdb->posts}.ID";
}, 10, 2);
Quando usarlo: siti piccoli (meno di 1.000 post), budget zero, necessità di miglioramento immediato senza dipendenze esterne.
Strategia 2: Plugin di Ricerca Specializzati (Costo: Medio)
Quando la query nativa non basta, i plugin di ricerca offrono funzionalità avanzate senza richiedere infrastruttura esterna. Abbiamo testato i principali su oltre 50 siti clienti:
| Plugin | Prezzo/anno | Ricerca fuzzy | Custom fields | WooCommerce | Indicizzazione | Performance (10k post) |
|---|---|---|---|---|---|---|
| SearchWP | $99 | Sì | Sì | Eccellente | Indice custom in DB | ~40ms |
| Ivory Search | $49 | Parziale | Sì | Buono | Indice custom in DB | ~60ms |
| Relevanssi | $99 | Sì | Sì | Buono | Indice fulltext in DB | ~50ms |
| Jetpack Search | Incluso Jetpack | Sì | Limitato | Base | Server-side (WordPress.com) | ~30ms |
| FiboSearch | $89 | Sì | Sì | Eccellente | Ajax live search | ~25ms |
Tempi misurati su ambiente staging con 10.000 post, PHP 8.3, MySQL 8.0, cache object abilitata.
SearchWP: La Nostra Scelta per Siti Complessi
Nella nostra esperienza, SearchWP è il plugin che offre il miglior rapporto qualità-prezzo per agenzie. Lo usiamo su 30+ siti clienti con questi vantaggi:
- Indicizzazione intelligente: crea un indice separato in database, non usa
LIKEsuwp_posts - Pesatura configurabile: puoi assegnare peso a titolo, contenuto, excerpt, custom field, taxonomie
- Ricerca fuzzy: tollera errori di battitura e variazioni singolare/plurale
- Integrazione WooCommerce: cerca in SKU, variazioni, attributi
- REST API: espone un endpoint
/wp-json/swp/searchper headless
// Configurazione SearchWP via functions.php
// Definisci un engine personalizzato per un cliente e-commerce
add_filter('searchwp\query\modifier', function($modifier, $args) {
// Aumenta il peso del titolo per prodotti
if ($args['engine'] === 'product_search') {
$modifier['weight']['title'] = 10;
$modifier['weight']['content'] = 3;
$modifier['weight']['meta']['_sku'] = 8;
$modifier['weight']['meta']['product_specs'] = 5;
}
return $modifier;
}, 10, 2);
// Hook per loggare le ricerche senza risultati (zero-results)
add_action('searchwp\query\results', function($results, $query) {
if (empty($results)) {
$term = $query->get('s');
// Salva per analisi: quali ricerche non trovano nulla?
wp_insert_post(array(
'post_type' => 'search_log',
'post_status' => 'private',
'post_title' => 'Zero results: ' . $term,
'post_date' => current_time('mysql'),
));
}
}, 10, 2);
Relevanssi: L’Alternativa Open Source
Relevanssi offre una versione gratuita con funzionalità sufficienti per siti piccoli. La versione Premium ($99/anno) aggiunge ricerca fuzzy avanzata, stemmer italiano e import/export degli indici.
// Attiva lo stemmer italiano in Relevanssi
add_filter('relevanssi_stemmer', function($stemmer, $term) {
// Relevanssi Premium include stemmer per italiano
return $stemmer;
}, 10, 2);
// Configura pesi personalizzati
add_filter('relevanssi_match', function($match, $term, $post) {
// Dai più peso ai post con immagine featured
if (has_post_thumbnail($post->ID)) {
$match->weight *= 1.2;
}
// Riduci peso ai post più vecchi di 2 anni
if (strtotime($post->post_date) < strtotime('-2 years')) {
$match->weight *= 0.8;
}
return $match;
}, 10, 3);
Strategia 3: Indice Fulltext MySQL (Costo: Basso-Medio)
Per siti che non vogliono plugin ma hanno bisogno di performance migliori, l’indice FULLTEXT di MySQL è un’opzione sottovalutata. Trasforma le ricerche da LIKE '%term%' (scansione completa tabella) a ricerche indicizzate in O(log n).
Implementazione pratica
// 1. Crea l'indice fulltext via WP-CLI o phpMyAdmin
// wp db query "ALTER TABLE wp_posts ADD FULLTEXT INDEX ft_search (post_title, post_content)"
// 2. Sostituisci la query di ricerca nativa
add_filter('posts_where', function($where, $query) {
global $wpdb;
if (!is_search() || !$query->is_main_query()) {
return $where;
}
$terms = esc_sql(sanitize_text_field($query->get('s')));
// Sostituisci LIKE con MATCH ... AGAINST
$where = preg_replace(
"/\({$wpdb->posts}\.post_title LIKE '%[^%]+%'\) OR \({$wpdb->posts}\.post_content LIKE '%[^%]+%'\)/",
"MATCH({$wpdb->posts}.post_title, {$wpdb->posts}.post_content) AGAINST('{$terms}' IN NATURAL LANGUAGE MODE)",
$where
);
return $where;
}, 10, 2);
// 3. Ordina per punteggio di rilevanza
add_filter('posts_orderby', function($orderby, $query) {
global $wpdb;
if (!is_search() || !$query->is_main_query()) {
return $orderby;
}
return "MATCH({$wpdb->posts}.post_title, {$wpdb->posts}.post_content)
AGAINST('{$terms}' IN NATURAL LANGUAGE MODE) DESC";
}, 10, 2);
Attenzione: l’indice FULLTEXT richiede MySQL 5.6+ o MariaDB 10.0.4+ ed è efficace solo con tabelle InnoDB. Per database WordPress molto grandi, considera l’uso di ngram parser per lingue non inglesi.
Strategia 4: Elasticsearch e ElasticPress (Costo: Alto)
Per siti con 50.000+ contenuti o requirement di ricerca complessa (facet, filtri aggregati, ricerca geografica), Elasticsearch è lo standard industriale. Il plugin ElasticPress integra Elasticsearch con WordPress.
Architettura tipica per un’agenzia
# docker-compose.yml per Elasticsearch + Kibana
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.12.0
environment:
- discovery.type=single-node
- xpack.security.enabled=false
- "ES_JAVA_OPTS=-Xms1g -Xmx1g"
volumes:
- es_data:/usr/share/elasticsearch/data
ports:
- "9200:9200"
restart: unless-stopped
kibana:
image: docker.elastic.co/kibana/kibana:8.12.0
ports:
- "5601:5601"
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
depends_on:
- elasticsearch
volumes:
es_data:
Indicizzazione con ElasticPress
// wp-config.php — Configura ElasticPress
define('EP_HOST', 'http://elasticsearch:9200');
// functions.php — Configura gli indici
add_filter('ep_indexable_post_types', function($post_types) {
// Indicizza solo i post type rilevanti
return array(
'post' => 'post',
'page' => 'page',
'product' => 'product',
);
});
add_filter('ep_post_sync_args', function($post_args, $post_id) {
// Aggiungi campi personalizzati all'indice
$post_args['meta'] = array(
'_sku' => get_post_meta($post_id, '_sku', true),
'product_specs' => get_post_meta($post_id, 'product_specs', true),
);
return $post_args;
}, 10, 2);
// Configura la pesatura dei campi di ricerca
add_filter('ep_query_weighting', function($weighting, $query) {
$weighting['fields'] = array(
'post_title' => 3.0,
'post_content' => 1.0,
'meta._sku.value' => 5.0,
'terms.product_cat.name' => 2.0,
);
return $weighting;
}, 10, 2);
Quando usarlo: siti con 50.000+ contenuti, e-commerce con cataloghi grandi, progetti headless che necessitano di API di ricerca performanti.
Costi infrastruttura: un nodo Elasticsearch con 2GB RAM costa circa $15-30/mese su DigitalOcean o Hetzner. Per produzione con alta disponibilità, il costo sale a $100-200/mese.
Strategia 5: MeiliSearch — L’Alternativa Leggera (Costo: Medio)
MeiliSearch è un motore di ricerca open-source scritto in Rust che offre performance paragonabili a Elasticsearch con un decimo delle risorse. È la nostra scelta preferita per siti medi (1.000-50.000 contenuti).
Deploy con Docker
# docker-compose.yml
version: '3.8'
services:
meilisearch:
image: getmeili/meilisearch:v1.6
environment:
- MEILI_MASTER_KEY=chiave-master-sicura
- MEILI_ENV=production
volumes:
- meili_data:/meili_data
ports:
- "7700:7700"
restart: unless-stopped
volumes:
meili_data:
Integrazione WordPress via REST API
// functions.php — Sincronizza i post su MeiliSearch
add_action('save_post', function($post_id, $post, $update) {
if (wp_is_post_revision($post_id) || $post->post_status !== 'publish') {
return;
}
$document = array(
'id' => $post_id,
'title' => $post->post_title,
'content' => wp_strip_all_tags($post->post_content),
'excerpt' => $post->post_excerpt,
'url' => get_permalink($post_id),
'date' => $post->post_date,
'thumbnail' => get_the_post_thumbnail_url($post_id, 'medium'),
'type' => $post->post_type,
'categories' => wp_get_post_terms($post_id, 'category', array('fields' => 'names')),
);
// Aggiungi custom field
$document['sku'] = get_post_meta($post_id, '_sku', true);
// Invia a MeiliSearch
$meili_url = 'http://meilisearch:7700';
$meili_key = defined('MEILI_API_KEY') ? MEILI_API_KEY : '';
wp_remote_post("{$meili_url}/indexes/agency_posts/documents?primaryKey=id", array(
'headers' => array(
'Authorization' => "Bearer {$meili_key}",
'Content-Type' => 'application/json',
),
'body' => json_encode(array($document)),
'timeout' => 10,
));
}, 10, 3);
// Endpoint REST API custom per la ricerca
add_action('rest_api_init', function() {
register_rest_route('agency/v1', '/search', array(
'methods' => 'GET',
'permission_callback' => '__return_true',
'callback' => function($request) {
$query = sanitize_text_field($request->get_param('q'));
$limit = min(50, absint($request->get_param('per_page') ?: 10));
$meili_url = 'http://meilisearch:7700';
$meili_key = defined('MEILI_API_KEY') ? MEILI_API_KEY : '';
$response = wp_remote_post("{$meili_url}/indexes/agency_posts/search", array(
'headers' => array(
'Authorization' => "Bearer {$meili_key}",
'Content-Type' => 'application/json',
),
'body' => json_encode(array(
'q' => $query,
'limit' => $limit,
'attributesToHighlight' => array('title', 'content'),
'highlightPreTag' => '',
'highlightPostTag' => '',
)),
'timeout' => 5,
));
if (is_wp_error($response)) {
return new WP_Error('search_error', 'Errore ricerca', array('status' => 500));
}
$body = json_decode(wp_remote_retrieve_body($response), true);
return rest_ensure_response(array(
'query' => $query,
'total' => $body['estimatedTotalHits'] ?? 0,
'results' => $body['hits'] ?? array(),
'processing_time_ms' => $body['processingTimeMs'] ?? 0,
));
},
));
});
Questo endpoint REST API restituisce risultati in 2-5ms anche con 50.000 documenti, con evidenziazione dei termini di ricerca e supporto typo-tolerance nativo. Perfetto per installazioni headless o per sostituire completamente il search nativo.
Ajax Live Search: L’Esperienza Utente che Converte
L’ottimizzazione dell’algoritmo è metà del lavoro. L’altra metà è l’esperienza utente. La ricerca Ajax live (risultati mentre l’utente digita) aumenta il tasso di utilizzo della ricerca del 40-60% secondo i nostri dati interni.
Implementazione Ajax Live Search senza plugin
// search.js — Vanilla JS, no dipendenze
class AgencySearch {
constructor(inputSelector, resultsSelector) {
this.input = document.querySelector(inputSelector);
this.results = document.querySelector(resultsSelector);
this.debounceTimer = null;
this.abortController = null;
this.input.addEventListener('input', this.handleInput.bind(this));
document.addEventListener('click', this.handleClickOutside.bind(this));
}
handleInput(e) {
const query = e.target.value.trim();
clearTimeout(this.debounceTimer);
if (query.length < 3) {
this.results.innerHTML = '';
this.results.classList.remove('active');
return;
}
this.debounceTimer = setTimeout(() => this.search(query), 200);
}
async search(query) {
if (this.abortController) {
this.abortController.abort();
}
this.abortController = new AbortController();
try {
const response = await fetch(
`/wp-json/agency/v1/search?q=${encodeURIComponent(query)}&per_page=5`,
{ signal: this.abortController.signal }
);
const data = await response.json();
this.renderResults(data);
} catch (err) {
if (err.name !== 'AbortError') {
console.error('Search error:', err);
}
}
}
renderResults(data) {
if (!data.results || data.results.length === 0) {
this.results.innerHTML = 'Nessun risultato trovato
';
this.results.classList.add('active');
return;
}
const html = data.results.map(hit => `
${hit.thumbnail ? `
` : ''}
${hit._formatted?.title || hit.title}
${hit._formatted?.content?.substring(0, 120) || ''}
`).join('');
this.results.innerHTML = html +
`Vedi tutti i risultati (${data.total})`;
this.results.classList.add('active');
}
handleClickOutside(e) {
if (!this.input.contains(e.target) && !this.results.contains(e.target)) {
this.results.classList.remove('active');
}
}
}
document.addEventListener('DOMContentLoaded', () => {
new AgencySearch('#search-input', '#search-results');
});
/* search.css — Styling minimale */
.search-results-container {
position: relative;
}
.search-results {
display: none;
position: absolute;
top: 100%;
left: 0;
right: 0;
background: #fff;
border: 1px solid #e0e0e0;
border-radius: 0 0 8px 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
max-height: 400px;
overflow-y: auto;
z-index: 1000;
}
.search-results.active { display: block; }
.search-result-item {
display: flex;
gap: 12px;
padding: 12px 16px;
text-decoration: none;
color: inherit;
border-bottom: 1px solid #f0f0f0;
transition: background 0.15s;
}
.search-result-item:hover { background: #f8f8f8; }
.search-result-item img {
width: 48px;
height: 48px;
object-fit: cover;
border-radius: 4px;
flex-shrink: 0;
}
.search-result-item h4 {
margin: 0 0 4px;
font-size: 14px;
font-weight: 600;
}
.search-result-item p {
margin: 0;
font-size: 13px;
color: #666;
line-height: 1.4;
}
.search-result-item mark {
background: #fff3cd;
padding: 0 2px;
border-radius: 2px;
}
.search-no-results {
padding: 20px 16px;
text-align: center;
color: #999;
}
.search-view-all {
display: block;
padding: 12px 16px;
text-align: center;
font-weight: 600;
color: #2271b1;
text-decoration: none;
border-top: 2px solid #f0f0f0;
}
Tracking e Analytics: Misurare la Ricerca Interna
Senza dati, non puoi ottimizzare. Il tracking della ricerca interna è fondamentale per capire cosa cercano gli utenti e cosa non trovano. Questi dati alimentano la strategia di contenuti e identificano gap nel catalogo.
Configurazione Google Analytics 4 + Site Search
// functions.php — Invia eventi di ricerca a GA4
add_action('wp_footer', function() {
if (!is_search()) return;
?>
'search_log',
'title' => 'Zero results: ' . $term,
'posts_per_page' => 1,
));
if (empty($existing)) {
wp_insert_post(array(
'post_type' => 'search_log',
'post_status' => 'private',
'post_title' => 'Zero results: ' . $term,
'post_content' => json_encode(array(
'term' => $term,
'url' => $_SERVER['REQUEST_URI'],
'referrer' => wp_get_referer(),
'timestamp' => current_time('mysql'),
)),
));
} else {
// Incrementa il contatore
$count = (int) get_post_meta($existing[0]->ID, '_search_count', true);
update_post_meta($existing[0]->ID, '_search_count', $count + 1);
}
}
});
Confronto: Quale Soluzione Scegliere per il Tuo Cliente
| Scenario | Soluzione consigliata | Costo annuo | Complessità |
|---|---|---|---|
| Blog con <500 articoli | Filtri WP_Query + fulltext MySQL | $0 | Bassa |
| Sito aziendale 500-2.000 contenuti | SearchWP o Relevanssi | $99 | Bassa |
| E-commerce WooCommerce 1.000-10.000 prodotti | SearchWP + FiboSearch Ajax | $188 | Media |
| Portale 10.000-50.000 contenuti | MeiliSearch + endpoint REST custom | $200-500 (server) | Alta |
| Marketplace 50.000+ contenuti, facet search | Elasticsearch + ElasticPress | $1.200-2.400 (server) | Alta |
| Headless WordPress con Next.js | MeiliSearch o Algolia + REST/GraphQL | $200-1.000 | Alta |
Automazione per Agenzie: Gestire la Ricerca su Multi-Sito
Per un’agenzia che gestisce 20+ siti clienti, configurare e mantenere la ricerca su ogni sito è un’operazione ripetitiva. Ecco come automatizziamo il deployment con WP-CLI:
#!/bin/bash
# deploy-search.sh — Deploy SearchWP + configurazione su un sito cliente
SITE_URL=$1
SITE_DIR=$2
if [ -z "$SITE_URL" ] || [ -z "$SITE_DIR" ]; then
echo "Usage: ./deploy-search.sh "
exit 1
fi
# 1. Installa SearchWP
wp --path="$SITE_DIR" plugin install searchwp --activate
# 2. Configura l'engine di ricerca
wp --path="$SITE_DIR" eval '
// Configurazione standard SearchWP per agenzie
$settings = array(
"engine" => array(
"post" => array(
"title" => 10,
"content" => 3,
"excerpt" => 2,
"slug" => 5,
"meta" => array(
"_seo_description" => 2,
"_excerpt" => 3,
),
),
"page" => array(
"title" => 10,
"content" => 3,
),
),
);
update_option("searchwp_settings", $settings);
'
# 3. Indicizza i contenuti
wp --path="$SITE_DIR" searchwp index --quiet
# 4. Verifica l'indice
wp --path="$SITE_DIR" searchwp stats
echo "✅ Search deployizzato su $SITE_URL"
# 5. Invia notifica
curl -s -X POST "$DISCORD_WEBHOOK" -H "Content-Type: application/json" -d "{"content": "🔍 Search deployizzato su $SITE_URL"}"
Checklist SEO per la Ricerca Interna
La ricerca interna ha un impatto diretto su SEO e GEO:
- Indicizza la pagina dei risultati: se la ricerca genera URL parametrici (es.
?s=term), assicurati che Google non le crawl-e conrobots.txtonoindex - Pagine di ricerca popolari come landing: identifica le ricerche frequenti e crea pagine dedicate ottimizzate per quelle keyword
- Breadcrumb sui risultati: aggiungi schema BreadcrumbList alle pagine di ricerca
- Tempi di risposta <200ms: la lentezza della ricerca impatta Core Web Vitals tramite INP
- No search results page utile: se non ci sono risultati, mostra contenuti correlati e suggerimenti, non una pagina vuota
Schema Markup per la Ricerca Interna
// functions.php — Aggiungi schema SearchAction al sito
add_filter('wp_head', function() {
if (!is_front_page() && !is_home()) return;
$schema = array(
'@context' => 'https://schema.org',
'@type' => 'WebSite',
'url' => home_url('/'),
'potentialAction' => array(
'@type' => 'SearchAction',
'target' => array(
'@type' => 'EntryPoint',
'urlTemplate' => home_url('/?s={search_term_string}'),
),
'query-input' => 'required name=search_term_string',
),
);
echo '' . "\n";
});
Questo schema SearchAction permette a Google di mostrare un search box sitelink direttamente nei risultati di ricerca, aumentando la visibilità e il CTR del sito del cliente.
FAQ: WordPress Search Interno
Quanto costa migliorare la ricerca interna di WordPress?
Il costo varia da $0 (filtri custom su WP_Query + indice fulltext MySQL) a $99/anno per plugin come SearchWP o Relevanssi, fino a $200-2.400/anno per infrastrutture esterne come MeiliSearch o Elasticsearch. Per la maggior parte dei siti clienti di un’agenzia, SearchWP a $99/anno è la soluzione con il miglior rapporto costo-beneficio.
La ricerca nativa di WordPress è sicura?
La ricerca nativa di WordPress è sicura se configurata correttamente: filtra sempre post_status su publish, escludi post type sensibili con pre_get_posts e valida l’input dell’utente con sanitize_text_field. Senza questi filtri, la ricerca può esporre contenuti privati o draft. Usa sempre plugin di sicurezza WordPress come Wordfence per monitorare accessi anomali.
Qual è il plugin migliore per la ricerca WordPress?
Non esiste un “migliore” assoluto. SearchWP è il più completo per siti complessi con custom field e WooCommerce. Relevanssi offre il miglior valore nella versione gratuita. FiboSearch è leader per l’Ajax live search su WooCommerce. Jetpack Search è gratuito ma limitato. Per siti headless o con 50.000+ contenuti, valuta motori esterni come MeiliSearch o Elasticsearch.
Come misurare le performance della ricerca interna?
Usa Google Analytics 4 con l’evento search per tracciare il volume di ricerche e i termini cercati. Monitora il processing_time_ms dei tuoi endpoint REST API. Tieni un log delle ricerche zero-results per identificare gap di contenuto. Traccia il CTR dei risultati di ricerca: se gli utenti cercano ma non cliccano, l’algoritmo di rilevanza non funziona.
La ricerca interna impatta la SEO?
Sì, indirettamente. Una ricerca interna veloce e precisa migliora il tempo sulla pagina, riduce il bounce rate e aumenta le conversioni — segnali positivi per Google. Inoltre, lo schema SearchAction può generare un search box sitelink nei risultati Google. Evita di indicizzare le pagine di ricerca parametriche (URL con ?s=) per prevenire contenuto thin duplicato.