Guides / Prompting and shipping
How to Add Search to Your App: From Simple Filters to Full-Text Search
How to add search to your app: simple filters, database full-text search, or a hosted search engine — which to pick, prompts to use, and mistakes to avoid.
Mythex Team · · 5 min read
To add search to your app, start with the simplest thing that works: a search box that calls a server route, which filters your database rows by matching the query against a few columns, plus filters for things like category or price. When that isn't good enough — you need relevance ranking, word stemming or many records — switch to your database's full-text search, and only move to a hosted search engine if you need strong typo tolerance or instant results over very large data. Whatever you pick, search must respect permissions: users should never find records they aren't allowed to see.
What "search" means for your app
Search covers a few different things, and most apps need more than one:
- Keyword search: a text box — "find listings mentioning 'garden'".
- Filters: structured choices — category, city, price range, date, status.
- Sorting: newest, cheapest, most relevant.
- Autocomplete: suggestions while typing.
- Typo tolerance: "restuarant" still finds "restaurant".
For a directory, job board or store, filters often matter more than the text box. Decide which of these you actually need before choosing a tool.
Your options
| Approach | How it works | Good for | Limits |
|---|---|---|---|
| Filter in the browser | Load the list, filter it in JavaScript | Small public lists (a few hundred items) | Sends all data to every visitor; slow with big lists |
| Database pattern match | Server query like "name contains the text", case-insensitive | Small to medium apps, admin tools | No ranking; can get slow on large tables; no stemming |
| Database full-text search | Postgres indexes words and ranks matches | Most content-heavy apps | Weak at typos unless you add fuzzy matching |
| Fuzzy matching (trigrams) | Postgres compares character sequences for similarity | Names, short fields, typo tolerance | Needs an extension and index; tuning takes care |
| Hosted search engine | A separate service indexes your data (Algolia, Meilisearch, Typesense, Elasticsearch and others) | Large catalogs, instant search, heavy typo tolerance | Another service to keep in sync, pay for and secure |
If your data already lives in Postgres, its built-in full-text search is a strong middle ground. It breaks text into words, reduces them to stems (so "running" matches "run"), ignores common words, and can rank results by how well they match. With the right index it stays fast on large tables.
Example prompts
A simple start:
Add a search box and filters to the listings page. Search should match the query against title and description, case-insensitive. Filters: category (dropdown), city (dropdown) and max price. Do the searching on the server with a paginated API route, 20 results per page. Keep the search and filters in the URL so results can be shared and the back button works. Show a friendly empty state when nothing matches.
Upgrading to full-text search:
Switch listing search to Postgres full-text search on title (weighted higher) and description. Add the right index, rank results by relevance, and keep the existing filters and pagination. Don't change any existing data.
Adding typo tolerance for names:
Add fuzzy matching on business name so small typos still find results. Use trigram similarity if available, with an index, and fall back to the current search if not.
Step by step
- List what people search for. Which fields (title, description, tags, name)? Which filters? Ask a few real users if you can.
- Start server-side. Add an API route that takes the query and filters, and returns one page of results. Don't load everything into the browser.
- Apply permissions in the query. If users only see their own records, or only published ones, that condition belongs in the same query as the search.
- Add pagination from day one — page numbers or "load more".
- Put search state in the URL (for example
?q=garden&city=leeds). Shareable links, working back button, and search engines can crawl filtered pages if you want them to. - Debounce search-as-you-type. Wait a few hundred milliseconds after typing stops before querying, so you don't send a request per keystroke.
- Add indexes once you know which columns you filter and search on.
- Upgrade to full-text search, then fuzzy matching, then a hosted engine — only when the simpler step fails real users.
- Test with real-looking data: hundreds or thousands of rows, odd characters, empty queries, very long queries, other languages if you support them.
Common mistakes
- Loading the whole table into the browser. Fine for 50 items, painful for 50,000, and it exposes every record — including ones the user shouldn't see.
- Search that ignores permissions. Search is a common leak: a private or draft record shows up because the search query forgot the "only mine" or "only published" condition.
- Building SQL from raw user input. Always use parameterised queries. An AI builder normally does, but check if you see strings being glued together.
- No empty state. "No results" with a suggestion (clear filters, check spelling) keeps people from leaving.
- No indexes. Search feels fine with test data and slows down as real data grows.
- Jumping straight to a search service. You then have to keep a second copy of your data in sync, handle deletes, and secure another set of keys — often for no visible gain.
- Forgetting mobile. Filters need to fit on a phone; a filter drawer or collapsible panel usually works better than a sidebar.
Checklist
- You know which fields are searched and which filters exist
- Search runs on the server and returns paginated results
- The query enforces the same permissions as the rest of the app
- User input is passed as parameters, never glued into SQL
- Search state lives in the URL
- Typing is debounced
- Searched and filtered columns are indexed
- Empty, no-result and error states are clear
- Tested with realistic data volumes and messy input
Adding search with Mythex
In an app built on Mythex, data usually lives in the project's own Postgres database, so you can start with the prompts above: pattern matching first, then Postgres full-text search when you need ranking. If you want a hosted search engine, bring your own account and key, store it as a project secret, and ask the agent to index and query it from the server, as described in Integrate any API.
Search is the core of many apps: see how to build a directory website, how to build a job board and how to build a marketplace for how it fits into the rest of the product.
Questions
What is the easiest way to add search to an app?
If your data is in a database, a server route that filters rows with a case-insensitive match on a few columns is the easiest start. For a small list that is already loaded in the browser, filtering in the browser is even simpler.
Do I need Algolia or Elasticsearch for search?
Usually not at first. Postgres full-text search handles word matching, ranking and thousands to millions of rows well. A hosted search engine is worth it when you need strong typo tolerance, instant results as you type across large data, or advanced relevance tuning.
Why doesn't my search find results with typos?
Basic matching and standard full-text search look for the words as typed (or their stems), so a misspelling misses. You need fuzzy matching, such as trigram similarity in Postgres or a search engine with typo tolerance.
Should search run in the browser or on the server?
On the server for anything beyond a small public list. Server-side search scales, respects permissions and doesn't send your whole dataset to every visitor.