WordPress Search Interno per Agenzie: Guida Completa all’Ottimizzazione [2026]

2 settembre 202613 minGuide

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_title e post_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 draft o private in 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 LIKE su wp_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/search per 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:

  1. Indicizza la pagina dei risultati: se la ricerca genera URL parametrici (es. ?s=term), assicurati che Google non le crawl-e con robots.txt o noindex
  2. Pagine di ricerca popolari come landing: identifica le ricerche frequenti e crea pagine dedicate ottimizzate per quelle keyword
  3. Breadcrumb sui risultati: aggiungi schema BreadcrumbList alle pagine di ricerca
  4. Tempi di risposta <200ms: la lentezza della ricerca impatta Core Web Vitals tramite INP
  5. 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.

Gestisci i siti WordPress dei tuoi clienti?

AgencyPilot ti dà report AI, uptime monitoring, backup e portale clienti in un’unica dashboard. Gratis per 3 siti.

Prova gratis
Leggi anche
Tutti gli articoli
Tutti gli articoli