Lovable prompt to add a search feature
Search is where Lovable often takes the shortcut of filtering fetched rows in the browser, which collapses once a table grows. This prompt forces Postgres full-text search with a tsvector column and GIN index behind a debounced, keyboard-friendly input, and it makes the tool prove that Row Level Security still holds for results.
Last updated
Add search so users can find {{resource}} records by typing.
Backend:
- Use Postgres full-text search in Supabase: a tsvector column on the {{resource}} table covering its name and description fields, a GIN index, and a trigger keeping the column current on insert and update. Do not fetch all rows and filter them in JavaScript.
- Sanitize the query text so punctuation or stray quotes cannot break the tsquery.
UI:
- A search input in the app header, focusable with the / key, showing a dropdown of the top 8 matches. Arrow keys move the highlight, Enter opens the record, Escape closes.
- Debounce keystrokes by roughly 300ms and discard out-of-order responses so a slow early request cannot overwrite a later query's results.
- A full results page at /search?q= listing all matches with matched terms highlighted, reached by pressing Enter with the input focused.
States and edge cases:
- Under 2 characters: show a hint, run no query.
- Zero matches: say so plainly, then offer close partial matches using an ilike fallback.
- Search must respect existing Row Level Security and never return rows the current user cannot already open.
- An empty q on the results page redirects home.
Match the current header and list styling; introduce no new visual language.
To verify: seed several records sharing a distinctive word, search it, confirm the dropdown and results page agree, then log in as a second user and confirm the first user's private rows never appear in their results.Customize it
Runs in your browser. Nothing you type here is sent anywhere.
Add search so users can find users records by typing. Backend: - Use Postgres full-text search in Supabase: a tsvector column on the users table covering its name and description fields, a GIN index, and a trigger keeping the column current on insert and update. Do not fetch all rows and filter them in JavaScript. - Sanitize the query text so punctuation or stray quotes cannot break the tsquery. UI: - A search input in the app header, focusable with the / key, showing a dropdown of the top 8 matches. Arrow keys move the highlight, Enter opens the record, Escape closes. - Debounce keystrokes by roughly 300ms and discard out-of-order responses so a slow early request cannot overwrite a later query's results. - A full results page at /search?q= listing all matches with matched terms highlighted, reached by pressing Enter with the input focused. States and edge cases: - Under 2 characters: show a hint, run no query. - Zero matches: say so plainly, then offer close partial matches using an ilike fallback. - Search must respect existing Row Level Security and never return rows the current user cannot already open. - An empty q on the results page redirects home. Match the current header and list styling; introduce no new visual language. To verify: seed several records sharing a distinctive word, search it, confirm the dropdown and results page agree, then log in as a second user and confirm the first user's private rows never appear in their results.
Same task in other tools
Questions about this prompt
Is full-text search overkill for my table?
For a few hundred rows and single-word queries, an ilike filter on one or two columns is fine; swap the backend section for that and keep the UI as is. Full text starts paying off with multi-word queries, ranking, and larger tables.
Can I get typo tolerance?
Ask Lovable to enable the pg_trgm extension in Supabase and use similarity scoring for the no-results fallback instead of ilike. That gives near-match suggestions without replacing the main tsvector path.
The dropdown shows stale results while I type. What is the fix?
Almost always missing request cancellation: an early slow response lands after a later fast one. Tell Lovable to tag each request with its query string and ignore any response whose tag no longer matches the current input.