A proof-of-concept implementation of an "omni search box" for Quran.com that can search across multiple content types and present results in an intelligent, consolidated manner.
- Unified Search Interface: Single search box with AI Chat/Search toggle
- Multiple Content Types: Searches across Quran, translations, tafsir, posts, courses, and articles
- Ayah-Centric Results: Consolidates results by verse, showing:
- Arabic Quran text
- Best-matching translation
- Relevant tafsir excerpts
- Related posts, courses, and articles
- Expandable drill-down for full result set
- Direct Content Hits: Links to articles, courses, and posts with excerpts
- Clean UI: Inspired by modern Islamic research platforms
- Node.js 18+
- npm or yarn
cd frontend
npm installnpm run devThe app will be available at http://localhost:5173
npm run buildfrontend/
├── src/
│ ├── components/ # React components
│ │ ├── Header.tsx
│ │ ├── SearchBox.tsx
│ │ ├── QuickActions.tsx
│ │ ├── SearchResults.tsx
│ │ ├── AyahCard.tsx
│ │ └── DirectHitCard.tsx
│ ├── data/
│ │ └── mockData.ts # Mock search responses
│ ├── types/
│ │ └── index.ts # TypeScript interfaces
│ ├── App.tsx
│ └── main.tsx
└── ...
The server lives in server/ and proxies GoodMem into the response format the UI expects.
cd server
export GOODMEM_API_KEY=gm_***
export GOODMEM_INSECURE_SSL=true
gradle runThe server defaults to http://localhost:7070 and exposes GET /api/search.
GOODMEM_BASE_URL(defaulthttps://omni-dev.quran.ai:8080)GOODMEM_API_KEY(required)GOODMEM_INSECURE_SSL(defaulttruefor self-signed TLS)GOODMEM_SPACE_IDS(optional,quran=...,translation=...etc)SEARCH_DEFAULT_LANGUAGE(defaulten)SEARCH_LIMIT_QURAN,SEARCH_LIMIT_TRANSLATION,SEARCH_LIMIT_TAFSIR,SEARCH_LIMIT_POST,SEARCH_LIMIT_COURSE,SEARCH_LIMIT_ARTICLESEARCH_RERANKER_ID(default019bd887-2953-7562-92b8-964abb5bffa4)SEARCH_RERANK_CANDIDATES(default100)SEARCH_RERANK_CHRONOLOGICAL_RESORT(defaultfalse)SEARCH_OVERVIEW_LLM_ID(default019bc775-3b20-767f-a15f-42cda8039b2c)SEARCH_OVERVIEW_SYS_PROMPT(optional; overrides the system prompt template)SEARCH_OVERVIEW_PROMPT(optional; overrides the user prompt template)SEARCH_OVERVIEW_TOKEN_BUDGET(default256)SEARCH_OVERVIEW_TEMP(default0.3)SEARCH_OVERVIEW_MAX_RESULTS(default8)SEARCH_OVERVIEW_CANDIDATES(default24)SEARCH_OVERVIEW_RELEVANCE_THRESHOLD(optional)
Deploy as two Railway services (mirrors goodcrm):
- Backend: set root directory to
server, usesserver/railway.toml+server/Dockerfile.- Required vars:
GOODMEM_API_KEY - Optional:
GOODMEM_BASE_URL,GOODMEM_INSECURE_SSL
- Required vars:
- Frontend: set root directory to
frontend, usesfrontend/railway.toml.- Set
VITE_API_BASE_URLto your backend URL (e.g.https://your-backend.up.railway.app)
- Set
Try these searches to see different result types:
ayat al-kursi- Shows consolidated ayah view with translations, tafsir, and related contentinterpretation of ayah 2:255- Tafsir-focused resultspatience- Returns multiple ayahs about patience with related reflectionsramadan- Direct hits for posts, courses, and articles about Ramadanpatience with family- Mix of ayah results and direct content hits
- React 18 with TypeScript
- Vite
- Tailwind CSS v4
- Lucide React (icons)
The frontend attempts to call /api/search and falls back to mock data if the backend is not running. The backend proxies GoodMem:
- REST API:
https://omni-dev.quran.ai:8080 - gRPC API:
https://omni-dev.quran.ai:9090
The response structure matches the UI types so the mock data and live search stay interchangeable.
When SEARCH_OVERVIEW_LLM_ID is set, the backend uses the GoodMem ChatPostProcessor to add an aiOverview summary to search responses.