A minimal web-based conversational search engine that combines web search capabilities (via Exa AI API) with AI-powered answer generation (via Mistral API). Get synthesized answers with source citations in a clean, modern interface.
- 🔍 Web Search Integration: Powered by Exa AI for relevant, real-time web content
- 🤖 AI-Generated Answers: Uses Mistral AI to synthesize comprehensive responses
- 📚 Source Citations: View and verify all sources used in answer generation
- ⚡ Streaming Responses: Progressive answer display for faster perceived performance
- 🎨 Modern UI: Clean, minimalist design built with Next.js and Tailwind CSS
- 🔒 Secure: API credentials stored server-side only
Before you begin, ensure you have the following installed:
- Node.js 18.x or higher
- npm or yarn package manager
You'll also need API keys from:
git clone <repository-url>
cd perplexity-clonenpm install
# or
yarn installCopy the example environment file:
cp .env.local.example .env.localEdit .env.local and add your API keys:
# Exa AI API Key
EXA_API_KEY=your_actual_exa_api_key
# Mistral AI API Key
MISTRAL_API_KEY=your_actual_mistral_api_key
# CORS Configuration (optional)
ALLOWED_ORIGIN=*npm run dev
# or
yarn devOpen http://localhost:3000 in your browser to see the application.
- Visit https://exa.ai
- Sign up for an account or log in
- Navigate to your dashboard or API settings
- Generate a new API key
- Copy the key and add it to your
.env.localfile
Documentation: Exa AI API Docs
- Visit https://console.mistral.ai
- Create an account or sign in
- Go to API Keys section in your account settings
- Create a new API key
- Copy the key and add it to your
.env.localfile
Documentation: Mistral AI API Docs
perplexity-clone/
├── app/
│ ├── api/
│ │ └── search/
│ │ └── route.ts # Backend API endpoint
│ ├── globals.css # Global styles
│ ├── layout.tsx # Root layout
│ └── page.tsx # Main search interface
├── components/
│ ├── AnswerDisplay.tsx # Answer rendering component
│ ├── ErrorMessage.tsx # Error display component
│ ├── LoadingIndicator.tsx # Loading state component
│ ├── SearchInput.tsx # Search input component
│ └── SourcesList.tsx # Source citations component
├── lib/
│ ├── exa-client.ts # Exa API integration
│ ├── mistral-client.ts # Mistral API integration
│ ├── prompt-formatter.ts # Prompt construction utilities
│ └── input-sanitizer.ts # Input validation and sanitization
├── .env.local.example # Environment variables template
└── README.md # This file
npm run devStarts the development server on http://localhost:3000
npm run buildCreates an optimized production build
npm run startRuns the production build (must run npm run build first)
npm testRuns the test suite using Vitest
npm run verify-securityVerifies that API credentials are not exposed in client-side code
npm run lintRuns ESLint to check code quality
Vercel is the easiest way to deploy Next.js applications:
-
Install Vercel CLI (optional):
npm install -g vercel
-
Deploy via Vercel Dashboard:
- Push your code to GitHub, GitLab, or Bitbucket
- Visit vercel.com
- Import your repository
- Configure environment variables in the Vercel dashboard:
EXA_API_KEYMISTRAL_API_KEYALLOWED_ORIGIN(set to your production domain)
- Deploy!
-
Deploy via CLI:
vercel
Follow the prompts and add environment variables when requested
Documentation: Next.js Deployment
- Push your code to a Git repository
- Visit netlify.com and create a new site
- Connect your repository
- Configure build settings:
- Build command:
npm run build - Publish directory:
.next
- Build command:
- Add environment variables in Netlify dashboard:
EXA_API_KEYMISTRAL_API_KEYALLOWED_ORIGIN
- Deploy!
-
Create a Dockerfile:
FROM node:18-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . RUN npm run build EXPOSE 3000 CMD ["npm", "start"]
-
Build and run:
docker build -t perplexity-clone . docker run -p 3000:3000 \ -e EXA_API_KEY=your_key \ -e MISTRAL_API_KEY=your_key \ perplexity-clone
When deploying to production, ensure you set:
EXA_API_KEY: Your Exa AI API keyMISTRAL_API_KEY: Your Mistral AI API keyALLOWED_ORIGIN: Your production domain (e.g.,https://yourdomain.com)NODE_ENV: Set toproduction(usually automatic)
- ✅ API keys are stored server-side only (never exposed to client)
- ✅ Input sanitization prevents XSS attacks
- ✅ CORS configured for production domain
- ✅ HTTPS required in production
- ✅ No conversation history stored (stateless queries)
Run npm run verify-security to verify API credentials are not exposed.
- Enter your question in the search box
- Press Enter or click the search button
- Wait for the AI to search the web and generate an answer
- View the synthesized answer with source citations
- Click on sources to explore further
Each query is independent - no conversation history is maintained.
- Verify your API keys are correctly set in
.env.local - Ensure there are no extra spaces or quotes around the keys
- Restart the development server after changing environment variables
- Check your internet connection
- Verify the Exa and Mistral APIs are accessible from your network
- Check if you've exceeded API rate limits
- You've hit the rate limit for Exa or Mistral API
- Wait a few moments before trying again
- Consider upgrading your API plan for higher limits
- Delete
.nextfolder andnode_modules - Run
npm installagain - Try
npm run buildagain
- Framework: Next.js 15+ with App Router
- Language: TypeScript
- Styling: Tailwind CSS
- APIs: Exa AI (search), Mistral AI (LLM)
- Testing: Vitest, React Testing Library, fast-check
- Deployment: Vercel, Netlify, or Docker
This is a minimal implementation focused on core functionality. Feel free to extend it with:
- Conversation history
- Multiple AI model options
- Advanced search filters
- User authentication
- Result caching
- Analytics
[Your License Here]
For issues or questions:
- Check the Exa AI Documentation
- Check the Mistral AI Documentation
- Review the Next.js Documentation
Built with using Next.js, Exa AI, and Mistral AI