Try it above or visit search-with-c1.vercel.app
What You’ll Learn
- How to connect C1 with search APIs using tool calling
- Building multi-provider search (Exa neural search + Google Gemini)
- Crafting system prompts for rich visual outputs
- Streaming search results in real-time
- Setting up C1Chat for conversational search UI
- Thread management for follow-up questions
Architecture Overview
Modern AI search apps follow this pattern:Setup
Prerequisites
- Node.js 18+
- Thesys API key from console.thesys.dev
- Choose one search provider:
- Exa API key from exa.ai (recommended for neural search)
- Google Gemini API key from ai.google.dev
- (Optional) Google Custom Search API key and CSE ID for image search
Create Next.js Project
npm
- TypeScript: Yes
- ESLint: Yes
- Tailwind CSS: Yes
- App Router: Yes
- Customize default import alias: No
Install Dependencies
npm
npm
npm
Environment Variables
Create a.env.local file:
Step 1: Set Up Search Tools
C1 uses OpenAI’s tool calling to trigger searches. Here’s how to define a search tool:Next.js
Step 2: Implement Search Providers
You have two options for search:Option A: Exa Neural Search
Exa provides AI-powered search with full page content extraction:exa-search.ts
Option B: Google Gemini with Grounding
Gemini 2.5 has built-in Google Search grounding:gemini-search.ts
Step 3: Create the Main API Endpoint
Now connect everything with C1:app/api/ask/route.ts
Step 4: Craft the Perfect System Prompt
The system prompt determines how C1 generates UI. Here’s a proven pattern for search apps:The key is being specific about when to use visual components and how to structure them. Vague prompts lead to inconsistent results.
Step 5: Enable Image Search
C1 generates image components, but needs actual image URLs to display them. Create an image search endpoint that C1 can call:app/api/search/image/route.ts
How Image Search Works
The C1 SDK handles images automatically through asearchImage callback:
Frontend (React)
- Backend C1 generates image components with descriptive alt text (e.g.,
alt="Eiffel Tower at sunset") - C1 SDK detects images with empty
srcattributes - SDK automatically calls your
searchImage(altText)function - Your function fetches the actual image URL from your
/api/search/imageendpoint - SDK updates the component with the real image URL
searchImage callback to C1Component.
The
searchImage callback gives you flexibility: use Google Images, Unsplash, Pexels, or your own image CDN. The SDK just needs a function that takes a query string and returns { url, thumbnailUrl }.Step 6: Add Caching (Optional but Recommended)
Cache responses to avoid re-searching identical queries:cache.ts
Step 7: Add Thread Management for Follow-ups (Optional)
To enable follow-up questions that reference previous searches, implement thread management:thread-cache.ts
Using Thread History
Update your main endpoint to include thread history:With thread context
Why Thread Management Matters
With threads, users can ask follow-up questions:Production tip: Use Redis or a database for thread storage instead of in-memory. In-memory storage is lost when your server restarts. The search-with-c1 repo includes Redis integration examples.
Step 8: Set Up the Frontend UI
Now create the conversational search interface using C1Chat:app/page.tsx
- Message history
- Streaming responses
- Thinking states
- Automatic thread management
- Image search integration
Image Search Integration
Create the image search handler (if you set up image search in Step 5):app/utils/searchImage.ts
app/api/search-image/route.ts
searchImage prop from C1Chat.
Step 9: Run Your Search App
Start the development server:npm
- “Best restaurants in Tokyo” - See visual results with images
- “How does quantum computing work?” - Get structured explanations
- Follow up with “What are the main applications?” - Test thread continuity
If you’re using Exa, the first search might be slower as it fetches full page content. Subsequent searches will be faster with caching enabled.
Key Concepts
Why use tool calling instead of direct API calls?
Why use tool calling instead of direct API calls?
Tool calling lets the LLM decide when to search and what to search for. The LLM might reformulate the query, do multiple searches, or skip searching if it has enough context from conversation history.
Exa vs Gemini: Which should I use?
Exa vs Gemini: Which should I use?
- Exa: Best for deep content analysis. Returns full page text for the LLM to process.
- Gemini: Faster and cheaper. Built-in search grounding with automatic result synthesis.
How does C1 know what UI to generate?
How does C1 know what UI to generate?
C1 analyzes the content + your system prompt. If content contains images, lists, or data, and your prompt encourages visual components, C1 will generate appropriate UI. The better your prompt, the better the UI.
Can I add my own data sources?
Can I add my own data sources?
Yes! Create additional tools for databases, APIs, or documents. C1 can combine web search with your private data.
Going to Production
Before deploying:- Add rate limiting to prevent API abuse
- Implement proper error handling for failed searches
- Set up monitoring for API costs and performance
- Add user authentication if needed
- Enable caching to reduce API calls
Full Example & Source Code
Try Live Demo
Experience the complete AI search app in action. Search for anything and see C1 generate beautiful, contextual UI in real-time.Try it now →
View Source Code
Complete implementation with thread management, error handling, caching, and deployment config. Everything from this guide and more.Star on GitHub →