Site Search Not Working? How to Make It Find What People Mean Without Paying for AI
A visitor types a word into your search box, sees "nothing found" and concludes you do not have it, even when you do. Most of these failures need no AI and no paid service to fix. Here is what people really type, what to build and in what order, how we built ours on plain MySQL in three languages, what our tests found wrong with it, and when Algolia, Elasticsearch, Meilisearch or vector search is the right call.
IN SHORT
What good site search does
Good site search forgives word forms, synonyms, typos and the wrong language, puts the page that answers the question first, never ends on an empty page, and logs what it could not find. On a site with up to tens of thousands of pages (our estimate), your existing database plus a few hundred lines of code can do most of this. A paid engine or vector search earns its cost on large catalogs with filters, or when people describe needs in words your pages never use.
The problem is common even where budgets are large. In Baymard Institute's 2026 benchmark of more than 170 e-commerce sites and apps, search rated "mediocre or worse" on 46% of desktop sites, 58% of mobile sites and 64% of apps (Baymard, updated April 2026). Those are stores with teams behind them, while a service site often has only the box that came with its CMS.
We rebuilt the search on our own site in October 2026 under one rule: no AI and no paid services. This article is what we learned, including the faults we found only while testing it for this text.
WHAT PEOPLE TYPE
What visitors type into the box
People search in their own words, and typing is slow and error-prone (Nielsen Norman Group, 2014). Your pages are written in your words. Almost every search failure is a gap between the two, and the gaps fall into a short list.
| What they type | What a default search does | What it should do |
|---|---|---|
| Another form of the word: "clinics", "designing" | Finds it or not, depending on how the page is worded | Match the start of each word |
| A different word: "shop" for "store", "price" for "cost" | Nothing, or unrelated pages | Treat a group of words as one |
| A typo: two letters swapped | Nothing | Offer the nearest real word and show its results |
| A whole question: "how much does a website cost" | Requires every word, or drowns in common ones | Separate the words that carry meaning |
| A need, not a page: "contacts", "return policy" | Lists articles that mention the word | Put the page that answers it on top |
| A short word: "car" | Also finds "career" and "cargo" | Match short terms as whole words |
| The wrong keyboard layout or language | Nothing | Retry the query in the other layout, then in the other language |
The fifth row is the one owners underestimate. In Baymard's 2026 figures, non-product searches such as "return policy" gave trouble on 66% of the sites studied, the highest of the query types in that article, against 20% for plain product-type searches. A visitor who searches your site for a phone number has already decided to talk to you, and the search answers with a blog post.
Every empty search is a visitor telling you what they wanted, in their words.
WHY DEFAULTS FAIL
Why the default search fails
Default search is built for a blog. WordPress is the clearest example because its code is public: each word is matched with LIKE '%word%' against three columns, the title, the excerpt and the content, and every word must be present (WordPress developer reference, November 2026). That design explains the symptoms owners complain about:
- Exact letters only: a typo or a synonym returns nothing.
- Pieces of words: %art% also matches "start" and "party", which is why a short query returns a long and strange list.
- One language: a query in another language looks for letters that the current version of the page does not contain.
- Only what is in those columns. Product attributes, custom fields and the text of pages built from templates, often your prices and your services, stay out of reach.
- A dead end: about 50% of e-commerce sites handle "no results" in ways that frustrate users, and such a page can send people to an outside search engine (Baymard, updated February 2025).
Other platforms start from a better place. Shopify says its online store search accounts for misspellings and uses related words and concepts by default (Shopify Help Center, November 2026), so a store there should first look at its product data before buying anything. If a platform has already grown past its plugins, the search is usually one symptom among several, as we describe in When Does a Business Outgrow WordPress?
The old shortcut, a box powered by Google, has narrowed too. Google's Custom Search JSON API is closed to new customers, existing customers have until January 1, 2027 to move, and Google names Vertex AI Search as the alternative (Google for Developers, November 2026).
BUILD ORDER
What to build, and in what order
The cheapest and most informative work comes first. On a closed platform the same list becomes a checklist for settings and apps.
- Log every search: query, language, number of results, what the search did to help. This takes an hour or two (our estimate) and tells you what the rest of the list should contain.
- Cover everything people read: articles, services, projects, FAQ answers, authors, vacancies and pages built from templates.
- Match word starts, and require every meaningful word: this alone removes much of the nonsense.
- Rank by title first: a page with the whole query in its title should beat a page that mentions the words in paragraph forty. Decide which types of page win a tie.
- Add synonym groups from the log: start with 10 to 20 groups you can already see in it, across all your languages.
- Add best-match cards: prices, contacts, vacancies, each industry you serve.
- Replace the empty page: other keyboard layout, nearest word, other language, and a line telling the visitor what was done.
- Add results as you type, last, because it multiplies every problem above.
If you cannot change the code yet, Google Analytics 4 can start step one today. Its enhanced measurement sends a view_search_results event with the search term whenever the page address carries a parameter called q, s, search, query or keyword (Google Analytics Help, November 2026). The default event leaves out the number of results, so zero-result queries need extra work. People also paste e-mail addresses into search boxes, and Google forbids sending personal data to Analytics, including in URL parameters (Google Analytics Help, November 2026), so turn on data redaction.
Keep a file of 30 to 50 real queries with the page you expect for each, in every language, and run it after each change, as part of the regression work described in How Much Testing Does a Website or App Need Before Launch?
OUR CASE
How our own search works
Our site runs on Laravel and MySQL, and the whole search is one controller of about 600 lines of PHP plus a small script for the live list, in English, Russian and Ukrainian. No external service is called.
Matching. Articles, projects and services have InnoDB FULLTEXT indexes, queried in boolean mode. Each query word becomes a required group of itself and its synonyms, each with a trailing asterisk, so a query for "website price" becomes roughly +(website* web* site* сайт*) +(price* cost* ціна* ...). The plus means the group must be present, and the asterisk means a word may begin that way (MySQL 8.4 manual). Everything except letters and digits is stripped first, because a stray character can act as an operator. Words under three letters are dropped unless nothing else is left, since MySQL's default minimum token size is 3 (MySQL 8.4 manual).
Coverage. Industries, vacancies and authors are searched with LIKE. The pages About, Partners, Investors and Pricing keep their text in templates, so the database knows nothing about them. The search fetches those live pages once a day per language and caches the heading, the meta description and the main text, so it searches what the visitor reads.
Synonyms. 27 groups written by hand across the three languages, such as сайт, вебсайт, website, web, site, веб. Most entries are word stems, so one line covers many forms in languages that decline their nouns. Short terms of three letters or fewer match only as whole words: on November 2, 2026, "car" brought up the Automotive card and "careers" brought up Vacancies.
Ranking. Scores are simple enough to read aloud:
| Signal | Points |
|---|---|
| The whole query is in the title, punctuation ignored | +50, plus up to 20 more for a shorter title |
| A query word or its synonym starts a word of the title | +10 per word |
| The full-text score from MySQL | Added as it is |
| Page type | Service +8, industry or template page +6, glossary term +4, project +2, FAQ answer -2, vacancy -12 |
These numbers are business decisions in code form: on equal words a service page answers better than an article, and a job advert should almost never beat either. A store would write a different table, with availability and margin in it, which is why search cannot simply be installed. In client projects that logic is built with the product, and the code, ranking rules and synonym lists are handed over to you under the contract with the rest of the system. On the FIAT Kharkiv dealership platform, for instance, customers find genuine spare parts by their vehicle's VIN: search shaped by what that business sells.
ZERO RESULTS
When nothing is found
An empty result starts a ladder, and the page says what was done.
Another keyboard layout. A person typing Russian or Ukrainian with the keyboard still on English gets gibberish: "ctj" for "сео". A lookup table turns the query into the other layout and tries again, even with a typo on top. This matters only where people type in more than one alphabet, so a US site in English and Spanish can skip it.
The nearest word. Every word of four letters or more from our titles goes into a vocabulary, cached for an hour. A query word missing from it is compared with that list by Levenshtein distance, the number of single-letter changes between two words: one change for words up to five letters, two for longer ones, and the more frequent word wins a tie. PHP's own levenshtein() is reported in the manual's user notes to work on bytes, which can count one Cyrillic letter as two changes, so we compute the distance on letters ourselves. On November 2, 2026, "development" with two letters swapped returned "Did you mean" and the services for development.
The other languages. Every page on our site exists in three languages, so if the words match the English version of a page, a visitor on the Russian site gets the Russian version, with a note saying so. What else changes between language versions is covered in Multilingual Website Design: What Changes Beyond Translation.
Best-match cards sit above the results, whether or not anything else was found. Words such as "price", "cost" or "budget" put a card for our pricing page on top, in any of the three languages. There are eight such intents, including contacts and vacancies, plus eight industries.
THE LOG
The zero-results log is a free business report
Every full search on our site adds one line to a monthly file: time, language, query, number of results, what the search did to help, which card it showed. That file holds no IP address and no cookie. Anything that looks like an e-mail or a phone number is masked before it is written, the query is cut at 120 characters, and only the first page of results counts.
A short command then prints three lists for any month: top queries, queries that found nothing, and queries the search had to help. We do not publish our figures, but the way to read them applies to any business.
| What you see in the log | What it probably means | What to do |
|---|---|---|
| A service or product you do not offer, asked for repeatedly | Demand you have not priced | Discuss it as a business question: add it, or say clearly that you do not do it |
| A thing you do offer, under a word you never use | Your vocabulary differs from your customers' | Add a synonym group, and use their word on the page |
| A question: delivery time, warranty, price | The answer is hidden or missing | Write it, or add a best-match card |
| A person's or client's name | Visitors checking your claims | Make sure that page exists and is easy to reach |
| Top queries that do find results | Your menu is failing them | Look at the navigation before the search |
In a store the same log shows missing products and attributes the catalog does not describe, which we cover in Intelligent Product Discovery: Search, Filters and Configurators for Complex Catalogs. Reading it is also part of our usability audit, from $1,500.
"Nothing found" is the one report your customers write for free.
Half an hour a month should be enough for most sites (our estimate): act on three lines, then see next month whether those queries have moved.
WHERE IT BREAKS
What our tests found wrong
We tested our own search for this article on November 2, 2026, through its public suggestion endpoint, which is not logged. It turned up faults that anyone building on MySQL full text may meet.
The stopword trap. The query "how much does a custom website cost" did not return our own article How Much Does a Custom Website Cost in 2026? among its first rows. Without the word "how", that article came first, right under the pricing card. Our reading of the MySQL manual explains it: "how" is on the default InnoDB stopword list, so it is not in the index, but a word with the truncation operator stays in a boolean query even if it is a stopword. So +(how*) demands a word beginning with "how", the index does not hold "how" itself, and a word like "however" is what passes. The list also holds what, when, where, who, for, from, with and the (MySQL 8.4 manual). Those are question words. We fixed it the same day: stopwords left the required part of the query and stay only for comparing with titles, so that article now comes right under the pricing card. Our Russian and Ukrainian test questions were fine, because the default list is mostly English.
The ladder started only at zero. "ctj" had stopped returning zero results, because our article on product discovery prints that very example, and now so does this one. The query found those articles, and the layout fix never started. A Russian word typed on the English site could do the same: one stray article containing it, and no fallback. We changed the trigger the same day: when no title holds the query, the layout fix and the other languages run as well, and they take over only if their own results have the query in a title. "ctj" leads to "сео" again.
Prefix matching has a price. The whole-word rule for short terms governs cards and synonyms. Results still match any word that starts that way, so the glossary term "Cart abandonment" appears under the Automotive card.
What it will not do at all. It does not understand meaning: words that appear on no page, with no synonym written for them, find nothing. Word stems are kept by hand. It ranks in PHP after loading every match, which is comfortable for thousands of documents and would be wrong for hundreds of thousands (our estimate).
ENGINE CHOICE
MySQL, Algolia, Elasticsearch, Meilisearch or vectors
Laravel's own documentation says of its built-in database search engine that for most applications it is all you need, and sends you to dedicated engines for typo tolerance, facets, vector search or geo-search at large scale (Laravel 13 documentation, November 2026). Prices below were checked in November 2026 and will move.
| Option | What it gives | Price, November 2026 | Right when |
|---|---|---|---|
| MySQL full text plus your own code | Word starts, required words, your ranking. No typos, no meaning, no facets | Nothing beyond your database and the development | Content and service sites up to tens of thousands of pages, products with a small catalog (our estimate) |
| Meilisearch | Typo tolerance by default, facets; Cyrillic and Arabic pipelines | Cloud from $20 a month; self-hosted is free under MIT | A mid-size catalog and a server you control |
| Algolia | Hosted, nothing to run yourself | 10,000 requests a month free on Grow, then $0.50 per 1,000; Grow Plus with AI features $1.75 per 1,000 | A store that wants a managed service and has a budget that scales with traffic |
| Elasticsearch | Fine control, language analyzers, large volumes (our view) | Hosted from $99 a month; self-managed free tier under the Elastic License | Large catalogs, several languages, an engineer who will own it |
| Vector or hybrid search | Finds pages by meaning, also across languages | Embedding from $0.02 per million tokens (OpenAI), plus the engine | People describe needs in words your pages never use |
Do the arithmetic for your own traffic. Algolia bills by search request, and its InstantSearch library sends one query per keystroke by default; it recommends debouncing, a delay of about 200 ms (Algolia documentation, November 2026). Suppose each search costs five requests after debouncing, which is our assumption. At 20,000 searches a month that is 100,000 requests, about $45 on Grow or $158 on Grow Plus. At 200,000 searches it is one million requests, about $495 or $1,733. Algolia calls its estimates directional. For many mid-size businesses the bigger question is a copy of the catalog on someone else's service, and what happens when the contract changes.
Check your languages before you sign. Elasticsearch has built-in analyzers for Spanish, Russian and Arabic, while Ukrainian needs a plugin (Elastic documentation, November 2026). Meilisearch documents pipelines for Cyrillic and Arabic scripts (Meilisearch documentation, November 2026).
Vector search is cheap to index and easy to overrate. At $0.02 per million tokens, embedding a thousand pages of about 1,500 tokens each costs about three cents (our arithmetic). The real costs are the extra service and a model call on each query. It also misses what people type most precisely: product codes, jargon, dates and names do better with keyword search, and Microsoft's hybrid search runs both in parallel (Microsoft Learn, updated September 2026). On Laravel, semantic search in the database engine needs PostgreSQL with pgvector, and MySQL 8.4 has no vector type in its data types chapter. Our rule: look at the zero-results log first. If it is full of descriptions rather than names, meaning search may pay. If it is full of typos and other words for the same thing, it will not. When visitors need a conversation rather than a list, that is a job for an AI website assistant.
We do not list search as a separate price. We build it into a web application, from $25,000, or an online store, from $25,000, where it shares its data model with filters and faceted navigation, and on an existing site we start by reading the log. All our prices are on the pricing page.
Read the log first; it usually picks the engine for you.
FAQ
Frequently asked questions
Why is my website search not working?
Usually it matches exact letters in a few database columns, so typos, synonyms and other languages return nothing and pages built from templates stay invisible. Type your top service with a typo, a synonym and as a question. If those fail, the search needs work and the content may be fine.
How can I improve site search without paying for AI?
Log every query first. Then cover all your content, match word starts, rank titles first, add synonyms from the log and best-match cards for prices and contacts, and replace the empty page with retries. Our own search does this on MySQL with no paid service.
Algolia, Meilisearch or Elasticsearch: which should I choose?
Algolia if you want a managed service and accept a bill tied to traffic: in November 2026, 10,000 requests a month free, then $0.50 per 1,000 on its Grow plan. Meilisearch if you want typo tolerance out of the box and can run a server or pay from $20 a month for its cloud. Elasticsearch for large volumes and deep control, with an engineer to own it.
Do I need vector or AI search on my site?
Only if the log shows people describing needs in words your pages never use. Keyword search does better on product codes, names and dates, so the two usually run side by side. If the log shows mostly typos and synonyms, those cost far less to fix.
What is a zero-results report and how do I get one?
It is the list of queries that found nothing, plus the ones the search had to correct. On your own code, write one line per search with the query, language and result count, e-mails and phone numbers masked, no IP. Google Analytics 4 records search terms, but it needs extra setup to know which ones returned nothing.
Sources
- Baymard Institute: E-commerce search query types, 2026 benchmark
- Baymard Institute: "No Results" pages
- MySQL 8.4 manual: Boolean full-text searches
- Meilisearch documentation: Typo tolerance settings
- Algolia: Pricing
People search your site and find nothing? Let's look at what they typed and what to fix first.
One notification a week with the new PERETZ articles. Nothing else.