
Añade en el archivo functions.php de tu tema un filtro sobre parse_query que convierta cualquier consulta de búsqueda en un 404, un filtro get_search_form que devuelva una cadena vacía, y quita el widget y el bloque de búsqueda. El código completo, probado en WordPress 7.1, está en el artículo; no hace falta ningún plugin.
Una web de presentación de cinco páginas, un sitio de una sola página, un portfolio: la búsqueda de WordPress no sirve de nada y su formulario estorba en el tema. Peor aún, la página de resultados existe incluso sin formulario, en la dirección /?s=mot, y muestra una página vacía o una lista de contenidos que no querías destacar. Así se desactiva por completo la búsqueda de WordPress, sin plugin, con un fragmento para functions.php.
Por qué desactivar la búsqueda
- No sirve de nada en un sitio pequeño: todo se alcanza desde el menú con un clic.
- Genera páginas de resultados sin valor, que los robots pueden pedir con cualquier palabra, lo que malgasta recursos del servidor y crea URL basura.
- El formulario que impone el tema a menudo no encaja en el diseño.
El código completo para functions.php
Colócalo en el archivo functions.php de tu tema hijo (o en un pequeño plugin propio, para que sobreviva a los cambios de tema). Cada bloque cierra una puerta distinta.
<?php
/**
* Desactiva la búsqueda de WordPress en la parte pública.
*/
// 1. Cualquier búsqueda por URL (/?s=mot o /search/mot/) se convierte en una página 404.
add_action( 'parse_query', function ( WP_Query $query ) {
if ( is_admin() || ! $query->is_main_query() || ! $query->is_search() ) {
return;
}
$query->is_search = false;
$query->set_404();
status_header( 404 );
nocache_headers();
} );
// 2. El formulario de búsqueda del tema deja de mostrarse.
add_filter( 'get_search_form', '__return_empty_string' );
// 3. Se retira el widget de búsqueda clásico.
add_action( 'widgets_init', function () {
unregister_widget( 'WP_Widget_Search' );
}, 11 );
// 4. El bloque «Buscar» del editor desaparece del menú de inserción.
add_filter( 'allowed_block_types_all', function ( $allowed ) {
if ( ! is_array( $allowed ) ) {
$registry = WP_Block_Type_Registry::get_instance();
$allowed = array_keys( $registry->get_all_registered() );
}
return array_values( array_diff( $allowed, [ 'core/search' ] ) );
} );
// 5. Se cierra el punto de acceso REST de búsqueda.
add_filter( 'rest_endpoints', function ( array $endpoints ) {
unset( $endpoints['/wp/v2/search'], $endpoints['/wp/v2/search/(?P<id>[\d]+)'] );
return $endpoints;
} );Lo que hace cada bloque:
- La consulta. En
parse_query, si la consulta principal es una búsqueda en la parte pública, se convierte en un 404 conset_404()y el código HTTP correspondiente.is_admin()deja intacta la búsqueda de la administración;is_main_query()evita tocar las consultas secundarias de los plugins. - El formulario.
get_search_form()es la función que llaman los temas para mostrar el formulario; el filtro hace que devuelva una cadena vacía. - El widget de los temas clásicos.
- El bloque de los temas basados en bloques. El filtro recibe o bien
true(todos los bloques permitidos), o bien una lista: en el primer caso se reconstruye la lista completa antes de quitar de ellacore/search. - La API REST.
/wp-json/wp/v2/search?search=motdevuelve ahora un errorrest_no_routeen lugar de una lista de resultados.
Comprobar
Bastan tres peticiones, en un navegador o con curl:
curl -s -o /dev/null -w "%{http_code}\n" "https://exemple.fr/?s=test"
# 404
curl -s "https://exemple.fr/wp-json/wp/v2/search?search=test" | head -c 120
# {"code":"rest_no_route","message":"No se ha encontrado ninguna ruta que coincida con la URL y el método de la solicitud."…
curl -s "https://exemple.fr/" | grep -c 'role="search"'
# 0: ya no hay formulario en la página (si el tema pasa por get_search_form)En la administración, la búsqueda de entradas, de páginas y de medios debe seguir funcionando.
Si el tema muestra su propio formulario
Algunos temas escriben el formulario directamente en sus plantillas (header.php, searchform.php) sin pasar por get_search_form(). El filtro entonces no tiene ningún efecto sobre lo que se ve. Dos opciones: sobrescribir esa plantilla en un tema hijo, u ocultar el formulario con CSS mientras tanto:
.search-form,
form[role="search"] {
display: none;
}El CSS solo oculta: el bloqueo de /?s= por el primer bloque de PHP sigue siendo imprescindible.
Variante: redirigir ?s= en .htaccess
Si prefieres no servir un 404 y llevar al usuario a la portada, una regla de Apache lo hace antes incluso de que WordPress se ejecute. Está limitada a la raíz del sitio para no tocar la búsqueda de la administración (wp-admin/edit.php?s=…).
# Colocar antes del bloque # BEGIN WordPress
RewriteEngine On
RewriteCond %{QUERY_STRING} (^|&)s= [NC]
RewriteRule ^$ /? [R=301,L]El ? final vacía la cadena de consulta de la redirección. Esta regla y el código PHP no se excluyen: la primera le ahorra al servidor ejecutar WordPress y el segundo sigue siendo la protección de referencia, también para los enlaces permanentes /search/mot/.
¿Y el plugin Disable Search?
Existe y hace lo mismo. En Gekkode, la línea editorial es no añadir un plugin para lo que un tema resuelve en treinta líneas: una dependencia menos que actualizar y un comportamiento que lees en tu propio código. Si administras varios sitios sin tema hijo, el plugin sigue siendo una opción razonable.
En la misma línea, limitar el acceso al escritorio de WordPress y migrar un sitio WordPress son otras dos operaciones que se hacen sin plugin.
Errores frecuentes
is_search() sin is_admin() rompe la búsqueda en las listas de entradas y de medios del escritorio. El código del artículo excluye la administración./?s=mot sigue estando al alcance de cualquiera que escriba la URL. Quien cierra la puerta es el filtro sobre parse_query, no la retirada del formulario.s= sin restricción de ruta redirige también wp-admin/edit.php?s=…. Limita la regla a la raíz del sitio.get_search_form(), el filtro no lo quita. Hay que modificar entonces la plantilla del tema (mejor la del hijo).

