## ✨ Add accent-insensitive search functionality ### 🎯 Overview Implements accent-insensitive search across all searchable fields in Twenty CRM. Users can now search for "jose" to find "José", "muller" to find "Müller", "cafe" to find "café", etc. ### 🔍 Problem Twenty's search functionality was accent-sensitive, requiring users to type exact accented characters to find records. This created a poor user experience, especially for international names and content. ### 💡 Solution Added PostgreSQL `unaccent` extension with a custom immutable wrapper function to enable accent-insensitive full-text search across all searchable field types. ### 📋 Changes Made **Modified Files:** - `packages/twenty-server/scripts/setup-db.ts` - `packages/twenty-server/src/engine/api/graphql/graphql-query-runner/utils/compute-where-condition-parts.ts` - `packages/twenty-server/src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util.ts` ### 🗄️ Database Setup (`setup-db.ts`) ```sql -- Added unaccent extension CREATE EXTENSION IF NOT EXISTS "unaccent"; -- Created immutable wrapper function CREATE OR REPLACE FUNCTION unaccent_immutable(text) RETURNS text AS $$ SELECT public.unaccent($1) $$ LANGUAGE sql IMMUTABLE; ``` ### 🔍 Search Vector Generation (`get-ts-vector-column-expression.util.ts`) Applied `public.unaccent_immutable()` to all searchable field types: - TEXT fields (job titles, names, etc.) - FULL_NAME fields (first/last names) - EMAILS fields (both email address and domain) - ADDRESS fields - LINKS fields - RICH_TEXT and RICH_TEXT_V2 fields ### 🔎 Query Processing (`compute-where-condition-parts.ts`) Enhanced search queries to use `public.unaccent_immutable()` for both: - Full-text search (`@@` operator with `to_tsquery`) - Pattern matching (`ILIKE` operator) ### 🧠 Technical Rationale: Why the Wrapper Function? **The Challenge:** PostgreSQL's built-in `unaccent()` is marked as **STABLE**, but `GENERATED ALWAYS AS` expressions (used for search vector columns) require **IMMUTABLE** functions. **The Solution:** Created an IMMUTABLE wrapper function that calls the underlying `unaccent()` function: - ✅ Satisfies PostgreSQL's immutability requirements for generated columns - ✅ Maintains the exact same functionality as the original `unaccent()` - ✅ Uses fully qualified `public.unaccent_immutable()` to ensure function resolution from workspace schemas **Alternative Approaches Considered:** - ❌ Modifying `search_path`: would affect workspace isolation - ❌ Computing unaccent at query time: would hurt performance - ❌ Using triggers: would complicate data consistency ### 🎯 Impact For **Person** records, accent-insensitive search now works on: - Name (first/last name): `"jose garcia"` finds `"José García"` - Email: `"jose@cafe.com"` finds `"josé@café.com"` - Job Title: `"manager"` finds `"Managér"` or `"Gerente de Café"` Applies to all searchable standard objects: - Companies, People, Opportunities, Notes, Tasks, etc. - Any custom fields of searchable types (TEXT, EMAILS, etc.) ### ✅ Testing - Database reset completes successfully - Workspace seeding works without errors - Search vectors generate with unaccent functionality - All searchable field types properly handle accented characters --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com>
The #1 Open-Source CRM
🌐 Website · 📚 Documentation · Roadmap ·
Discord ·
Figma
Installation
See:
🚀 Self-hosting
🖥️ Local Setup
Does the world need another CRM?
We built Twenty for three reasons:
CRMs are too expensive, and users are trapped. Companies use locked-in customer data to hike prices. It shouldn't be that way.
A fresh start is required to build a better experience. We can learn from past mistakes and craft a cohesive experience inspired by new UX patterns from tools like Notion, Airtable or Linear.
We believe in Open-source and community. Hundreds of developers are already building Twenty together. Once we have plugin capabilities, a whole ecosystem will grow around it.
What You Can Do With Twenty
Please feel free to flag any specific needs you have by creating an issue.
Below are a few features we have implemented to date:
- Personalize layouts with filters, sort, group by, kanban and table views
- Customize your objects and fields
- Create and manage permissions with custom roles
- Automate workflow with triggers and actions
- Emails, calendar events, files, and more
Personalize layouts with filters, sort, group by, kanban and table views
Customize your objects and fields
Create and manage permissions with custom roles
Automate workflow with triggers and actions
Emails, calendar events, files, and more
Stack
- TypeScript
- Nx
- NestJS, with BullMQ, PostgreSQL, Redis
- React, with Recoil, Emotion and Lingui
Thanks
Thanks to these amazing services that we use and recommend for UI testing (Chromatic), code review (Greptile), catching bugs (Sentry) and translating (Crowdin).
Join the Community
- Star the repo
- Subscribe to releases (watch -> custom -> releases)
- Follow us on Twitter or LinkedIn
- Join our Discord
- Improve translations on Crowdin
- Contributions are, of course, most welcome!




