Skip to main content
Build your own AI-powered search engine that generates beautiful, interactive UI instead of just returning links. This guide teaches you the architecture and techniques behind apps like Perplexity and Google AI Search.
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:
The key innovation: instead of returning raw search results, we let C1 generate contextual, visual UI based on what the user searched for.

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
When prompted, select:
  • TypeScript: Yes
  • ESLint: Yes
  • Tailwind CSS: Yes
  • App Router: Yes
  • Customize default import alias: No

Install Dependencies

npm
If using Google Gemini instead of Exa:
npm
Optional (for image search):
npm

Environment Variables

Create a .env.local file:
We recommend Exa for better neural search results. Get your API key from exa.ai.

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
The writeThinkItem calls show users what’s happening while search runs in the background. This creates a better UX than silent loading.

Step 2: Implement Search Providers

You have two options for 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.
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 a searchImage callback:
Frontend (React)
The flow:
  1. Backend C1 generates image components with descriptive alt text (e.g., alt="Eiffel Tower at sunset")
  2. C1 SDK detects images with empty src attributes
  3. SDK automatically calls your searchImage(altText) function
  4. Your function fetches the actual image URL from your /api/search/image endpoint
  5. SDK updates the component with the real image URL
You don’t need to manually handle image fetching - just provide the 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 }.
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:
Without threads, the second question would fail because the AI has no context from the first search.
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
C1Chat provides the complete conversational UI out of the box, including:
  • 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
Create the image search API endpoint:
app/api/search-image/route.ts
If you skipped Step 5 (image search), simply omit the searchImage prop from C1Chat.

Step 9: Run Your Search App

Start the development server:
npm
Open http://localhost:3000 and try these searches:
  1. “Best restaurants in Tokyo” - See visual results with images
  2. “How does quantum computing work?” - Get structured explanations
  3. 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

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: 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.
Many apps let users choose (see the live demo).
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.
Yes! Create additional tools for databases, APIs, or documents. C1 can combine web search with your private data.

Going to Production

Before deploying:
  1. Add rate limiting to prevent API abuse
  2. Implement proper error handling for failed searches
  3. Set up monitoring for API costs and performance
  4. Add user authentication if needed
  5. 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 →