How to Add a Live Search Button in WordPress Without a Plugin

Live Search Button in WordPress

Adding a live search bar to WordPress can make it much easier for visitors to find your posts, pages, and products.

The good news is that you do not need to install another WordPress plugin just to add live search.

In this beginner-friendly guide, I will show you how to add a live search box in WordPress without a plugin using a simple copy-and-paste code.

You do not need to understand PHP, JavaScript, AJAX, or CSS to follow this tutorial.

Simply copy the code, paste it into your WordPress website, and add the shortcode wherever you want the search box to appear.

The finished live search will:

  • Search while the visitor is typing
  • Show matching posts instantly
  • Search WordPress posts and pages
  • Search WooCommerce products
  • Show the featured image
  • Show the post or product category
  • Work on desktop and mobile
  • Allow visitors to click a result immediately
  • Work without installing a dedicated search plugin

Let’s get started.

What Does the Live Search Look Like?

When someone starts typing into the search box, matching results will automatically appear underneath it.

The visitor does not need to press the Search button before seeing suggestions.

They can simply click the result they want.

This makes searching your WordPress website much faster and easier.

Step 1: Back Up Your WordPress Website

Before adding custom code to WordPress, it is always a good idea to make a backup.

This is especially important if you are going to edit your theme’s files.

If your hosting company provides automatic backups, make sure you have a recent backup available.

Step 2: Open Your Code Manager Plugin

Install and activate a code manager plugin if you don’t have installed on your website. You can use plugins like WP code, code snippets that allows you to load your custom php, html, css, js files in different pages of your website.

Step 3: Copy and Paste the Live Search Code

Copy the complete code below.

<?php
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}
function khs_live_search_shortcode() {

	static $instance = 0;
	$instance++;

	$input_id   = 'khs-search-input-' . $instance;
	$results_id = 'khs-search-results-' . $instance;

	ob_start();
	?>
	<form
		class="khs-search"
		role="search"
		method="get"
		action="<?php echo esc_url( home_url( '/' ) ); ?>"
	>
		<div class="khs-search__box">

			<span class="khs-search__icon" aria-hidden="true">
				<svg
					width="20"
					height="20"
					viewBox="0 0 24 24"
					fill="none"
					stroke="currentColor"
					stroke-width="2"
					stroke-linecap="round"
					stroke-linejoin="round"
				>
					<circle cx="11" cy="11" r="8"></circle>
					<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
				</svg>
			</span>

			<label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>">
				Search posts
			</label>

			<input
				id="<?php echo esc_attr( $input_id ); ?>"
				class="khs-search__input"
				type="search"
				name="s"
				placeholder="Search..."
				autocomplete="off"
				aria-autocomplete="list"
				aria-controls="<?php echo esc_attr( $results_id ); ?>"
				aria-expanded="false"
			/>

			<button class="khs-search__button" type="submit">
				<span class="khs-search__button-text">Search</span>

				<svg
					class="khs-search__button-icon"
					width="18"
					height="18"
					viewBox="0 0 24 24"
					fill="none"
					stroke="currentColor"
					stroke-width="2"
					aria-hidden="true"
				>
					<circle cx="11" cy="11" r="8"></circle>
					<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
				</svg>
			</button>

		</div>

		<div
			id="<?php echo esc_attr( $results_id ); ?>"
			class="khs-search__results"
			role="listbox"
			hidden
		></div>
	</form>
	<?php

	return ob_get_clean();
}
add_shortcode( 'live_post_search', 'khs_live_search_shortcode' );

function khs_ajax_live_search() {

	$term = isset( $_GET['term'] )
		? sanitize_text_field( wp_unslash( $_GET['term'] ) )
		: '';

	$term = trim( $term );

	if ( strlen( $term ) < 2 ) {
		wp_send_json_success( array() );
	}

	$term = substr( $term, 0, 80 );

	global $wpdb;

	$contains = '%' . $wpdb->esc_like( $term ) . '%';
	$starts   = $wpdb->esc_like( $term ) . '%';

	$rows = $wpdb->get_results(
		$wpdb->prepare(
			"
			SELECT ID, post_title
			FROM {$wpdb->posts}
			WHERE post_status = 'publish'
				AND post_type IN ('post', 'page', 'product')
				AND post_title != ''
				AND post_title LIKE %s
			ORDER BY
				CASE
					WHEN post_title LIKE %s THEN 0
					ELSE 1
				END,
				post_date DESC
			LIMIT 8
			",
			$contains,
			$starts
		)
	);

	$results = array();

	if ( $rows ) {
		foreach ( $rows as $row ) {
			$results[] = array(
				'title' => html_entity_decode(
					get_the_title( $row->ID ),
					ENT_QUOTES,
					get_bloginfo( 'charset' )
				),
				'url' => get_permalink( $row->ID ),
			);
		}
	}

	wp_send_json_success( $results );
}

add_action( 'wp_ajax_khs_live_search', 'khs_ajax_live_search' );
add_action( 'wp_ajax_nopriv_khs_live_search', 'khs_ajax_live_search' );

function khs_live_search_styles() {
	?>
	<style id="khs-live-search-css">

		.khs-search {
			position: relative;
			width: min(100%, 420px);
			min-width: 240px;
			margin: 0;
			z-index: 999;
		}

		.khs-search *,
		.khs-search *::before,
		.khs-search *::after {
			box-sizing: border-box;
		}

		.khs-search__box {
			display: flex;
			align-items: center;
			width: 100%;
			min-height: 44px;
			background: #ffffff;
			border: 1px solid #d7dce2;
			border-radius: 8px;
			overflow: hidden;
			transition: border-color 0.2s ease, box-shadow 0.2s ease;
		}

		.khs-search__box:focus-within {
			border-color: #1e73be;
			box-shadow: 0 0 0 3px rgba(30, 115, 190, 0.12);
		}

		.khs-search__icon {
			display: flex;
			align-items: center;
			justify-content: center;
			flex: 0 0 auto;
			margin-left: 14px;
			color: #667085;
		}

		.khs-search__input {
			flex: 1 1 auto;
			width: 100%;
			min-width: 0;
			height: 44px;
			padding: 8px 12px;
			margin: 0;
			border: 0 !important;
			border-radius: 0 !important;
			outline: 0 !important;
			box-shadow: none !important;
			background: transparent !important;
			color: #222;
			font-size: 15px;
			line-height: 1.4;
		}

		.khs-search__input::placeholder {
			color: #8a919e;
			opacity: 1;
		}

		.khs-search__button {
			align-self: stretch;
			display: flex;
			align-items: center;
			justify-content: center;
			gap: 6px;
			min-width: 78px;
			margin: 0;
			padding: 0 15px;
			border: 0;
			border-radius: 0;
			background: #1e73be;
			color: #fff;
			font-size: 14px;
			font-weight: 600;
			line-height: 1;
			cursor: pointer;
			transition: opacity 0.2s ease;
		}

		.khs-search__button:hover {
			opacity: 0.9;
		}

		.khs-search__button-icon {
			display: none;
		}

		.khs-search__results {
			position: absolute;
			top: calc(100% + 7px);
			left: 0;
			right: 0;
			z-index: 99999;
			max-height: 360px;
			overflow-y: auto;
			padding: 6px;
			background: #ffffff;
			border: 1px solid #e2e5e9;
			border-radius: 9px;
			box-shadow:
				0 12px 28px rgba(0, 0, 0, 0.12),
				0 2px 6px rgba(0, 0, 0, 0.05);
		}

		.khs-search__results[hidden] {
			display: none !important;
		}

		.khs-search__result {
			display: block;
			width: 100%;
			padding: 10px 12px;
			border-radius: 6px;
			color: #222;
			font-size: 14px;
			font-weight: 500;
			line-height: 1.45;
			text-decoration: none !important;
			transition: background 0.15s ease, color 0.15s ease;
		}

		.khs-search__result:hover,
		.khs-search__result.is-active {
			background: #f2f6fa;
			color: #1e73be;
		}

		.khs-search__message,
		.khs-search__loading {
			padding: 11px 12px;
			color: #667085;
			font-size: 13px;
		}

		@media (max-width: 1024px) {
			.khs-search {
				width: min(100%, 360px);
			}

			.khs-search__button {
				min-width: 65px;
				padding-left: 12px;
				padding-right: 12px;
			}
		}

		@media (max-width: 767px) {
			.khs-search {
				width: 100%;
				min-width: 0;
			}

			.khs-search__box {
				min-height: 42px;
			}

			.khs-search__input {
				height: 42px;
				font-size: 16px;
			}

			.khs-search__button {
				min-width: 48px;
				width: 48px;
				padding: 0;
			}

			.khs-search__button-text {
				display: none;
			}

			.khs-search__button-icon {
				display: block;
			}

			.khs-search__results {
				max-height: 300px;
			}
		}

	</style>
	<?php
}
add_action( 'wp_head', 'khs_live_search_styles', 50 );

function khs_live_search_script() {

	$ajax_url = admin_url( 'admin-ajax.php' );
	?>
	<script id="khs-live-search-js">
	document.addEventListener('DOMContentLoaded', function () {

		const ajaxUrl = <?php echo wp_json_encode( $ajax_url ); ?>;

		document.querySelectorAll('.khs-search').forEach(function (form) {

			const input   = form.querySelector('.khs-search__input');
			const results = form.querySelector('.khs-search__results');

			if (!input || !results) {
				return;
			}

			let timer = null;
			let activeIndex = -1;
			let requestController = null;

			function closeResults() {
				results.hidden = true;
				results.innerHTML = '';
				activeIndex = -1;
				input.setAttribute('aria-expanded', 'false');
			}

			function openResults() {
				results.hidden = false;
				input.setAttribute('aria-expanded', 'true');
			}

			function getItems() {
				return Array.from(results.querySelectorAll('.khs-search__result'));
			}

			function setActive(index) {
				const items = getItems();

				if (!items.length) {
					activeIndex = -1;
					return;
				}

				items.forEach(function (item) {
					item.classList.remove('is-active');
					item.setAttribute('aria-selected', 'false');
				});

				if (index < 0) {
					index = items.length - 1;
				}

				if (index >= items.length) {
					index = 0;
				}

				activeIndex = index;
				items[activeIndex].classList.add('is-active');
				items[activeIndex].setAttribute('aria-selected', 'true');

				items[activeIndex].scrollIntoView({
					block: 'nearest'
				});
			}

			function showMessage(message) {
				results.innerHTML = '';

				const div = document.createElement('div');
				div.className = 'khs-search__message';
				div.textContent = message;

				results.appendChild(div);
				openResults();
			}

			function showLoading() {
				results.innerHTML = '';

				const div = document.createElement('div');
				div.className = 'khs-search__loading';
				div.textContent = 'Searching...';

				results.appendChild(div);
				openResults();
			}

			function renderResults(items) {
				results.innerHTML = '';
				activeIndex = -1;

				if (!items.length) {
					showMessage('No matching posts found.');
					return;
				}

				items.forEach(function (item, index) {
					const link = document.createElement('a');

					link.className = 'khs-search__result';
					link.href = item.url;
					link.textContent = item.title;

					link.setAttribute('role', 'option');
					link.setAttribute('aria-selected', 'false');
					link.dataset.index = index;

					link.addEventListener('mouseenter', function () {
						setActive(index);
					});

					results.appendChild(link);
				});

				openResults();
			}

			async function runSearch() {
				const term = input.value.trim();

				if (term.length < 2) {
					closeResults();
					return;
				}

				if (requestController) {
					requestController.abort();
				}

				requestController = new AbortController();
				showLoading();

				const url =
					ajaxUrl +
					'?action=khs_live_search&term=' +
					encodeURIComponent(term);

				try {
					const response = await fetch(url, {
						method: 'GET',
						credentials: 'same-origin',
						signal: requestController.signal
					});

					if (!response.ok) {
						throw new Error('Search request failed');
					}

					const data = await response.json();

					if (input.value.trim() !== term) {
						return;
					}

					if (data.success && Array.isArray(data.data)) {
						renderResults(data.data);
					} else {
						showMessage('No matching posts found.');
					}

				} catch (error) {
					if (error.name === 'AbortError') {
						return;
					}

					closeResults();
				}
			}

			input.addEventListener('input', function () {
				clearTimeout(timer);

				const term = input.value.trim();

				if (term.length < 2) {
					closeResults();
					return;
				}

				timer = setTimeout(runSearch, 250);
			});

			input.addEventListener('keydown', function (event) {
				const items = getItems();

				if (event.key === 'ArrowDown') {
					if (!items.length) {
						return;
					}

					event.preventDefault();
					setActive(activeIndex + 1);

				} else if (event.key === 'ArrowUp') {
					if (!items.length) {
						return;
					}

					event.preventDefault();
					setActive(activeIndex - 1);

				} else if (event.key === 'Enter') {
					if (activeIndex >= 0 && items[activeIndex]) {
						event.preventDefault();
						window.location.href = items[activeIndex].href;
					}

				} else if (event.key === 'Escape') {
					closeResults();
					input.blur();
				}
			});

			input.addEventListener('focus', function () {
				if (
					input.value.trim().length >= 2 &&
					results.children.length
				) {
					openResults();
				}
			});

			document.addEventListener('click', function (event) {
				if (!form.contains(event.target)) {
					closeResults();
				}
			});
		});
	});
	</script>
	<?php
}
add_action( 'wp_footer', 'khs_live_search_script', 50 );
<?php

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Live Search Shortcode
 *
 * Usage:
 * [live_post_search]
 */
function khs_live_search_shortcode() {

	static $instance = 0;
	$instance++;

	$input_id   = 'khs-search-input-' . $instance;
	$results_id = 'khs-search-results-' . $instance;

	ob_start();
	?>
	<form
		class="khs-search"
		role="search"
		method="get"
		action="<?php echo esc_url( home_url( '/' ) ); ?>"
	>
		<div class="khs-search__box">

			<span class="khs-search__icon" aria-hidden="true">
				<svg
					width="20"
					height="20"
					viewBox="0 0 24 24"
					fill="none"
					stroke="currentColor"
					stroke-width="2"
					stroke-linecap="round"
					stroke-linejoin="round"
				>
					<circle cx="11" cy="11" r="8"></circle>
					<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
				</svg>
			</span>

			<label
				class="screen-reader-text"
				for="<?php echo esc_attr( $input_id ); ?>"
			>
				Search posts
			</label>

			<input
				id="<?php echo esc_attr( $input_id ); ?>"
				class="khs-search__input"
				type="search"
				name="s"
				placeholder="Search..."
				autocomplete="off"
				aria-autocomplete="list"
				aria-controls="<?php echo esc_attr( $results_id ); ?>"
				aria-expanded="false"
			/>

			<button class="khs-search__button" type="submit">

				<span class="khs-search__button-text">
					Search
				</span>

				<svg
					class="khs-search__button-icon"
					width="18"
					height="18"
					viewBox="0 0 24 24"
					fill="none"
					stroke="currentColor"
					stroke-width="2"
					aria-hidden="true"
				>
					<circle cx="11" cy="11" r="8"></circle>
					<line x1="21" y1="21" x2="16.65" y2="16.65"></line>
				</svg>

			</button>

		</div>

		<div
			id="<?php echo esc_attr( $results_id ); ?>"
			class="khs-search__results"
			role="listbox"
			hidden
		></div>

	</form>
	<?php

	return ob_get_clean();
}

add_shortcode(
	'live_post_search',
	'khs_live_search_shortcode'
);


/**
 * AJAX Live Search
 */
function khs_ajax_live_search() {

	$term = isset( $_GET['term'] )
		? sanitize_text_field( wp_unslash( $_GET['term'] ) )
		: '';

	$term = trim( $term );

	/*
	 * Require at least 2 characters.
	 */
	if ( strlen( $term ) < 2 ) {
		wp_send_json_success( array() );
	}

	/*
	 * Limit search length.
	 */
	$term = substr( $term, 0, 80 );

	global $wpdb;

	$contains = '%' . $wpdb->esc_like( $term ) . '%';
	$starts   = $wpdb->esc_like( $term ) . '%';

	/*
	 * Search posts, pages and WooCommerce products.
	 */
	$rows = $wpdb->get_results(
		$wpdb->prepare(
			"
			SELECT ID, post_title
			FROM {$wpdb->posts}
			WHERE post_status = 'publish'
				AND post_type IN ('post', 'page', 'product')
				AND post_title != ''
				AND post_title LIKE %s
			ORDER BY
				CASE
					WHEN post_title LIKE %s THEN 0
					ELSE 1
				END,
				post_date DESC
			LIMIT 8
			",
			$contains,
			$starts
		)
	);

	$results = array();

	if ( $rows ) {

		foreach ( $rows as $row ) {

			$post_id   = (int) $row->ID;
			$post_type = get_post_type( $post_id );

			/*
			 * ----------------------------------------
			 * CATEGORY / CONTENT TYPE LABEL
			 * ----------------------------------------
			 */
			$category = '';

			/*
			 * Standard WordPress post category.
			 */
			if ( 'post' === $post_type ) {

				$categories = get_the_category( $post_id );

				if ( ! empty( $categories ) ) {

					$category = $categories[0]->name;

				} else {

					$category = 'Post';
				}
			}

			/*
			 * WooCommerce product category.
			 */
			elseif ( 'product' === $post_type ) {

				$product_categories = wp_get_post_terms(
					$post_id,
					'product_cat',
					array(
						'fields' => 'names',
					)
				);

				if (
					! is_wp_error( $product_categories )
					&& ! empty( $product_categories )
				) {

					$category = $product_categories[0];

				} else {

					$category = 'Product';
				}
			}

			/*
			 * Pages don't normally have categories,
			 * so display "Page".
			 */
			elseif ( 'page' === $post_type ) {

				$category = 'Page';
			}


			/*
			 * ----------------------------------------
			 * FEATURED IMAGE
			 * ----------------------------------------
			 */
			$image = get_the_post_thumbnail_url(
				$post_id,
				'thumbnail'
			);


			/*
			 * ----------------------------------------
			 * RESULT DATA
			 * ----------------------------------------
			 */
			$results[] = array(

				'title' => html_entity_decode(
					get_the_title( $post_id ),
					ENT_QUOTES,
					get_bloginfo( 'charset' )
				),

				'url' => get_permalink( $post_id ),

				'category' => $category,

				'image' => $image ? esc_url_raw( $image ) : '',
			);
		}
	}

	wp_send_json_success( $results );
}

add_action(
	'wp_ajax_khs_live_search',
	'khs_ajax_live_search'
);

add_action(
	'wp_ajax_nopriv_khs_live_search',
	'khs_ajax_live_search'
);


/**
 * Live Search CSS
 */
function khs_live_search_styles() {
	?>

	<style id="khs-live-search-css">

		/*
		 * ========================================
		 * SEARCH CONTAINER
		 * ========================================
		 */

		.khs-search {
			position: relative;
			width: min(100%, 420px);
			min-width: 240px;
			margin: 0;
			z-index: 999;
		}

		.khs-search *,
		.khs-search *::before,
		.khs-search *::after {
			box-sizing: border-box;
		}


		/*
		 * ========================================
		 * SEARCH BOX
		 * ========================================
		 */

		.khs-search__box {
			display: flex;
			align-items: center;
			width: 100%;
			min-height: 44px;
			background: #ffffff;
			border: 1px solid #d7dce2;
			border-radius: 8px;
			overflow: hidden;
			transition:
				border-color 0.2s ease,
				box-shadow 0.2s ease;
		}

		.khs-search__box:focus-within {
			border-color: #1e73be;
			box-shadow:
				0 0 0 3px rgba(30, 115, 190, 0.12);
		}


		/*
		 * Search icon
		 */

		.khs-search__icon {
			display: flex;
			align-items: center;
			justify-content: center;
			flex: 0 0 auto;
			margin-left: 14px;
			color: #667085;
		}


		/*
		 * Search input
		 */

		.khs-search__input {
			flex: 1 1 auto;
			width: 100%;
			min-width: 0;
			height: 44px;
			padding: 8px 12px;
			margin: 0;

			border: 0 !important;
			border-radius: 0 !important;
			outline: 0 !important;
			box-shadow: none !important;

			background: transparent !important;
			color: #222;

			font-size: 15px;
			line-height: 1.4;
		}

		.khs-search__input::placeholder {
			color: #8a919e;
			opacity: 1;
		}


		/*
		 * Search button
		 */

		.khs-search__button {
			align-self: stretch;

			display: flex;
			align-items: center;
			justify-content: center;
			gap: 6px;

			min-width: 78px;

			margin: 0;
			padding: 0 15px;

			border: 0;
			border-radius: 0;

			background: #1e73be;
			color: #ffffff;

			font-size: 14px;
			font-weight: 600;
			line-height: 1;

			cursor: pointer;

			transition: opacity 0.2s ease;
		}

		.khs-search__button:hover {
			opacity: 0.9;
		}

		.khs-search__button-icon {
			display: none;
		}


		/*
		 * ========================================
		 * RESULTS DROPDOWN
		 * ========================================
		 */

		.khs-search__results {
			position: absolute;

			top: calc(100% + 7px);
			left: 0;
			right: 0;

			z-index: 99999;

			max-height: 420px;
			overflow-y: auto;

			padding: 6px;

			background: #ffffff;

			border: 1px solid #e2e5e9;
			border-radius: 9px;

			box-shadow:
				0 12px 28px rgba(0, 0, 0, 0.12),
				0 2px 6px rgba(0, 0, 0, 0.05);
		}

		.khs-search__results[hidden] {
			display: none !important;
		}


		/*
		 * ========================================
		 * INDIVIDUAL SEARCH RESULT
		 * ========================================
		 */

		.khs-search__result {
			display: flex;
			align-items: center;
			gap: 12px;

			width: 100%;

			padding: 9px 10px;

			border-radius: 7px;

			color: #222;

			text-decoration: none !important;

			transition:
				background 0.15s ease,
				color 0.15s ease;
		}

		.khs-search__result:hover,
		.khs-search__result.is-active {
			background: #f2f6fa;
		}


		/*
		 * ========================================
		 * RESULT PREVIEW IMAGE
		 * ========================================
		 */

		.khs-search__result-image {
			display: block;

			flex: 0 0 58px;

			width: 58px;
			height: 58px;

			margin: 0;

			border-radius: 7px;

			object-fit: cover;
			object-position: center;

			background: #f1f3f5;
		}


		/*
		 * ========================================
		 * RESULT TEXT AREA
		 * ========================================
		 */

		.khs-search__result-content {
			display: flex;
			flex: 1 1 auto;
			flex-direction: column;
			align-items: flex-start;
			justify-content: center;

			gap: 4px;

			min-width: 0;
		}


		/*
		 * ========================================
		 * CATEGORY LABEL
		 * ========================================
		 */

		.khs-search__result-category {
			display: inline-block;

			max-width: 100%;

			color: #1e73be;

			font-size: 10px;
			font-weight: 700;
			line-height: 1.25;

			letter-spacing: 0.06em;
			text-transform: uppercase;

			white-space: nowrap;
			overflow: hidden;
			text-overflow: ellipsis;
		}


		/*
		 * ========================================
		 * RESULT TITLE
		 * ========================================
		 */

		.khs-search__result-title {
			display: block;

			width: 100%;

			color: #222;

			font-size: 14px;
			font-weight: 600;
			line-height: 1.4;

			transition: color 0.15s ease;
		}

		.khs-search__result:hover
		.khs-search__result-title,
		.khs-search__result.is-active
		.khs-search__result-title {
			color: #1e73be;
		}


		/*
		 * ========================================
		 * MESSAGE / LOADING
		 * ========================================
		 */

		.khs-search__message,
		.khs-search__loading {
			padding: 11px 12px;

			color: #667085;

			font-size: 13px;
			line-height: 1.4;
		}


		/*
		 * ========================================
		 * TABLET
		 * ========================================
		 */

		@media (max-width: 1024px) {

			.khs-search {
				width: min(100%, 360px);
			}

			.khs-search__button {
				min-width: 65px;
				padding-left: 12px;
				padding-right: 12px;
			}
		}


		/*
		 * ========================================
		 * MOBILE
		 * ========================================
		 */

		@media (max-width: 767px) {

			.khs-search {
				width: 100%;
				min-width: 0;
			}

			.khs-search__box {
				min-height: 42px;
			}

			.khs-search__input {
				height: 42px;
				font-size: 16px;
			}

			.khs-search__button {
				min-width: 48px;
				width: 48px;
				padding: 0;
			}

			.khs-search__button-text {
				display: none;
			}

			.khs-search__button-icon {
				display: block;
			}

			.khs-search__results {
				max-height: 340px;
			}

			.khs-search__result {
				gap: 10px;
				padding: 8px;
			}

			.khs-search__result-image {
				flex-basis: 50px;
				width: 50px;
				height: 50px;
			}

			.khs-search__result-title {
				font-size: 13px;
			}

			.khs-search__result-category {
				font-size: 9px;
			}
		}

	</style>

	<?php
}

add_action(
	'wp_head',
	'khs_live_search_styles',
	50
);


/**
 * Live Search JavaScript
 */
function khs_live_search_script() {

	$ajax_url = admin_url( 'admin-ajax.php' );
	?>

	<script id="khs-live-search-js">

	document.addEventListener(
		'DOMContentLoaded',
		function () {

			const ajaxUrl =
				<?php echo wp_json_encode( $ajax_url ); ?>;

			document
				.querySelectorAll('.khs-search')
				.forEach(function (form) {

					const input =
						form.querySelector(
							'.khs-search__input'
						);

					const results =
						form.querySelector(
							'.khs-search__results'
						);

					if (!input || !results) {
						return;
					}


					let timer = null;

					let activeIndex = -1;

					let requestController = null;


					/*
					 * Close results
					 */
					function closeResults() {

						results.hidden = true;

						results.innerHTML = '';

						activeIndex = -1;

						input.setAttribute(
							'aria-expanded',
							'false'
						);
					}


					/*
					 * Open results
					 */
					function openResults() {

						results.hidden = false;

						input.setAttribute(
							'aria-expanded',
							'true'
						);
					}


					/*
					 * Get selectable results
					 */
					function getItems() {

						return Array.from(
							results.querySelectorAll(
								'.khs-search__result'
							)
						);
					}


					/*
					 * Keyboard active result
					 */
					function setActive(index) {

						const items = getItems();

						if (!items.length) {

							activeIndex = -1;

							return;
						}

						items.forEach(
							function (item) {

								item.classList.remove(
									'is-active'
								);

								item.setAttribute(
									'aria-selected',
									'false'
								);
							}
						);


						if (index < 0) {

							index = items.length - 1;
						}


						if (index >= items.length) {

							index = 0;
						}


						activeIndex = index;


						items[activeIndex]
							.classList.add('is-active');


						items[activeIndex]
							.setAttribute(
								'aria-selected',
								'true'
							);


						items[activeIndex]
							.scrollIntoView({
								block: 'nearest'
							});
					}


					/*
					 * Message
					 */
					function showMessage(message) {

						results.innerHTML = '';

						const div =
							document.createElement('div');

						div.className =
							'khs-search__message';

						div.textContent = message;

						results.appendChild(div);

						openResults();
					}


					/*
					 * Loading state
					 */
					function showLoading() {

						results.innerHTML = '';

						const div =
							document.createElement('div');

						div.className =
							'khs-search__loading';

						div.textContent =
							'Searching...';

						results.appendChild(div);

						openResults();
					}


					/*
					 * Render AJAX results
					 */
					function renderResults(items) {

						results.innerHTML = '';

						activeIndex = -1;


						if (!items.length) {

							showMessage(
								'No matching posts found.'
							);

							return;
						}


						items.forEach(
							function (item, index) {

								/*
								 * Result link
								 */
								const link =
									document.createElement(
										'a'
									);

								link.className =
									'khs-search__result';

								link.href = item.url;

								link.setAttribute(
									'role',
									'option'
								);

								link.setAttribute(
									'aria-selected',
									'false'
								);

								link.dataset.index =
									index;


								/*
								 * Featured image
								 */
								if (item.image) {

									const image =
										document.createElement(
											'img'
										);

									image.className =
										'khs-search__result-image';

									image.src =
										item.image;

									image.alt = '';

									image.loading =
										'lazy';

									image.decoding =
										'async';

									link.appendChild(
										image
									);
								}


								/*
								 * Text content wrapper
								 */
								const content =
									document.createElement(
										'span'
									);

								content.className =
									'khs-search__result-content';


								/*
								 * Category / type label
								 */
								if (item.category) {

									const category =
										document.createElement(
											'span'
										);

									category.className =
										'khs-search__result-category';

									category.textContent =
										item.category;

									content.appendChild(
										category
									);
								}


								/*
								 * Post title
								 */
								const title =
									document.createElement(
										'span'
									);

								title.className =
									'khs-search__result-title';

								title.textContent =
									item.title;

								content.appendChild(
									title
								);


								/*
								 * Add content to link
								 */
								link.appendChild(
									content
								);


								/*
								 * Mouse hover keyboard state
								 */
								link.addEventListener(
									'mouseenter',
									function () {

										setActive(
											index
										);
									}
								);


								results.appendChild(
									link
								);
							}
						);


						openResults();
					}


					/*
					 * AJAX search
					 */
					async function runSearch() {

						const term =
							input.value.trim();


						if (term.length < 2) {

							closeResults();

							return;
						}


						/*
						 * Cancel previous request
						 */
						if (requestController) {

							requestController.abort();
						}


						requestController =
							new AbortController();


						showLoading();


						const url =
							ajaxUrl +
							'?action=khs_live_search&term=' +
							encodeURIComponent(term);


						try {

							const response =
								await fetch(
									url,
									{
										method: 'GET',
										credentials: 'same-origin',
										signal:
											requestController.signal
									}
								);


							if (!response.ok) {

								throw new Error(
									'Search request failed'
								);
							}


							const data =
								await response.json();


							/*
							 * Ignore outdated response
							 */
							if (
								input.value.trim() !== term
							) {

								return;
							}


							if (
								data.success &&
								Array.isArray(data.data)
							) {

								renderResults(
									data.data
								);

							} else {

								showMessage(
									'No matching posts found.'
								);
							}

						} catch (error) {

							if (
								error.name ===
								'AbortError'
							) {

								return;
							}

							closeResults();
						}
					}


					/*
					 * Input event
					 */
					input.addEventListener(
						'input',
						function () {

							clearTimeout(timer);

							const term =
								input.value.trim();


							if (term.length < 2) {

								closeResults();

								return;
							}


							timer = setTimeout(
								runSearch,
								250
							);
						}
					);


					/*
					 * Keyboard navigation
					 */
					input.addEventListener(
						'keydown',
						function (event) {

							const items =
								getItems();


							if (
								event.key ===
								'ArrowDown'
							) {

								if (!items.length) {
									return;
								}

								event.preventDefault();

								setActive(
									activeIndex + 1
								);

							}

							else if (
								event.key ===
								'ArrowUp'
							) {

								if (!items.length) {
									return;
								}

								event.preventDefault();

								setActive(
									activeIndex - 1
								);

							}

							else if (
								event.key ===
								'Enter'
							) {

								if (
									activeIndex >= 0 &&
									items[activeIndex]
								) {

									event.preventDefault();

									window.location.href =
										items[
											activeIndex
										].href;
								}

							}

							else if (
								event.key ===
								'Escape'
							) {

								closeResults();

								input.blur();
							}
						}
					);


					/*
					 * Reopen on focus
					 */
					input.addEventListener(
						'focus',
						function () {

							if (
								input.value.trim().length >= 2 &&
								results.children.length
							) {

								openResults();
							}
						}
					);


					/*
					 * Close when clicking outside
					 */
					document.addEventListener(
						'click',
						function (event) {

							if (
								!form.contains(
									event.target
								)
							) {

								closeResults();
							}
						}
					);

				});
		}
	);

	</script>

	<?php
}

add_action(
	'wp_footer',
	'khs_live_search_script',
	50
);

Now create a code snippet and select the type as PHP snippets.

Step 4: Add the Live Search Box to WordPress

The code creates a new shortcode:

[live_post_search]

You can now use this shortcode anywhere on your website where WordPress supports shortcodes.

For example, edit the page where you want your search bar to appear.

Add a Shortcode block and paste. > Then save or update the page. > Visit the page on the front end.

You should now see your new WordPress live search bar.

A live search box is especially useful in the website header because visitors can access it from almost every page.

If your theme or page builder supports shortcodes in the header, simply add:

[live_post_search]

to the appropriate shortcode element.

Where you place it depends on your theme or page builder.

Common locations include:

  • Next to the main navigation menu
  • Above the navigation menu
  • Inside a desktop header
  • Inside a mobile menu
  • Next to the shopping cart icon
  • Inside a sidebar

What Does the Search Include?

By default, this code searches three types of WordPress content:

  • Blog posts
  • Pages
  • WooCommerce products

This makes the search useful for both normal WordPress websites and WooCommerce stores.

How to Make the Search Bar Wider

The default maximum width is: width: min(100%, 420px);

If you want a wider search box, change: 420px to something larger.

For example: width: min(100%, 600px);

If you want it to use all available space, you can use: width: 100%;

How to Change the Featured Image Size

Search result images are currently approximately: 58 × 58 pixels

You can change this by finding:

.khs-search__result-image {
	flex: 0 0 58px;
	width: 58px;
	height: 58px;
}

For a smaller thumbnail, you could use:

.khs-search__result-image {
	flex: 0 0 45px;
	width: 45px;
	height: 45px;
}

For a larger thumbnail:

.khs-search__result-image {
	flex: 0 0 70px;
	width: 70px;
	height: 70px;
}

Keep the width and height the same if you want square thumbnails.

How to Show More Live Search Results

The code displays up to 8 search results.

To change this, search for: LIMIT 8

For example, to display 10 results, change it to: LIMIT 10

For a clean dropdown, I recommend keeping the number reasonably small.

Around 5 to 10 results is normally enough for live search.

FAQs

Yes. The code includes a mobile layout.

On smaller screens:

  • The search bar uses the available width.
  • The button changes to a search icon.
  • Search result images become smaller.
  • Titles remain easy to read.
  • Results stay inside a scrollable dropdown.

You do not need to create a separate mobile search box.

Yes.

If WooCommerce is installed, published products can appear in the live results.

The search can show the product’s:

  • Featured image
  • Product category
  • Product name

Visitors can click the product to go directly to its product page.

No.

The live suggestions make the normal search box better, but visitors can still submit a normal WordPress search.

For example, someone can type: WordPress

and either select one of the live suggestions or press the Search button.

If they press Search without selecting a suggestion, WordPress opens its normal search results page.

This gives visitors both options.

Sometimes the search dropdown may appear behind another part of the website.

This is usually caused by the design of the theme, header builder, or Elementor container.

The search already uses a high z-index, but a parent container may have: overflow: hidden;

If you are using Elementor, check the container or section that contains the search bar.

Try setting its overflow option to: Visible

instead of: Hidden

This often solves the problem.

A normal WordPress search requires the visitor to enter a keyword, submit the search form, and then open a separate results page.

Live search can make this process quicker.

For example, imagine a visitor wants to find: “How to Install WordPress”

They begin typing: “install”

Your website can immediately display: “How to Install WordPress”

The visitor clicks it and goes directly to the article.

This can be especially useful for websites with lots of content.

Adding live search does not directly guarantee higher Google rankings.

Its main purpose is to improve the experience for your visitors.

A well-organized website should make it easy for users to find important content, products, and pages.

Live search can be particularly helpful for:

  • Large blogs
  • Tutorial websites
  • News websites
  • WooCommerce stores
  • Documentation websites
  • Magazine websites
  • Websites with hundreds of pages

Think of live search as a useful navigation improvement rather than an SEO shortcut.

Not for this solution.

There are many WordPress search plugins available, and some offer advanced features.

However, if all you want is a simple live search with:

  • Instant suggestions
  • Featured images
  • Categories
  • Posts
  • Pages
  • WooCommerce products

then adding another plugin may not be necessary.

The code in this tutorial gives you a lightweight custom solution that you control.t.

Yes. Add an Elementor Shortcode widget and paste [live_post_search] inside it.

Yes. Find #1e73be in the code and replace it with your preferred brand color.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *

Hostinger Hosting
Get 20% Discount on Checkout
Hostinger managed Wordpress hosting
Get 20% Discount on Checkout