import React, { useState, useCallback } from 'react'; import { groundedSearch } from '../services/geminiService'; import { Spinner } from '../components/Spinner'; import { GroundingChunk } from '../types'; import { MarkdownRenderer } from '../components/MarkdownRenderer'; const GroundedSearchModule: React.FC = () => { const [prompt, setPrompt] = useState(''); const [tool, setTool] = useState<'googleSearch' | 'googleMaps'>('googleSearch'); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const [response, setResponse] = useState(null); const [chunks, setChunks] = useState([]); const [location, setLocation] = useState(null); const [locationError, setLocationError] = useState(null); const handleSearch = useCallback(async () => { if (!prompt.trim()) { setError('Please enter a search query.'); return; } setIsLoading(true); setError(null); setResponse(null); setChunks([]); let searchLocation: GeolocationCoordinates | undefined = undefined; if(tool === 'googleMaps') { if (!location) { try { const pos = await new Promise((resolve, reject) => { navigator.geolocation.getCurrentPosition(resolve, reject); }); setLocation(pos.coords); searchLocation = pos.coords; } catch (err) { setLocationError('Could not get location. Please enable location services. Search will proceed without it.'); } } else { searchLocation = location; } } try { const result = await groundedSearch(prompt, tool, searchLocation); setResponse(result.text); if (result.candidates?.[0]?.groundingMetadata?.groundingChunks) { setChunks(result.candidates[0].groundingMetadata.groundingChunks); } } catch (e: any) { setError(e.message || 'An unknown error occurred.'); } finally { setIsLoading(false); } }, [prompt, tool, location]); return (

Grounded Search

Get up-to-date, verifiable information by grounding Gemini's responses with Google Search or Google Maps.

setPrompt(e.target.value)} placeholder="e.g., Who won the latest F1 race? or Good Italian restaurants nearby?" className="flex-grow bg-gray-700 border border-gray-600 rounded-md p-3 focus:outline-none focus:ring-2 focus:ring-cyan-500 text-white" disabled={isLoading} />
{locationError &&

{locationError}

}
{isLoading && } {error &&

{error}

} {response && (
{chunks.length > 0 && (

Sources:

    {chunks.map((chunk, index) => { const uri = chunk.web?.uri || chunk.maps?.uri; const title = chunk.web?.title || chunk.maps?.title; if (!uri) return null; return
  • {title}
  • })}
)}
)}
); }; export default GroundedSearchModule;