Create a simple Google search bar component with React π΅π»β
We'll create a Google-style search bar component in React in about 7 minutes.
Here's how the final result will look:
And here's a video walkthrough (featuring me):
Step 1: Set Up Your React Environment
- Ensure you have Node.js installed on your system.
node -v
If you don't have Node.js installed, download and install it: https://nodejs.org/en/download/
- Create a new React project using Vite:
npm create vite@latest google-search-bar
cd google-search-bar
Then select React > JavaScript.
- Install our packages:
npm install
npm install lucide-react
We use the lucide-react
package for icons.
Step 2: Create the GoogleSearchBar Component
Create a new file called GoogleSearchBar.jsx
in your google-search-bar/src
and add the following code:
import React from 'react'
import { Search, Mic } from 'lucide-react'
const GoogleSearchBar = () => {
// Component code will go here
}
export default GoogleSearchBar
Step 3: Add Sample Data
Update GoogleSearchBar.jsx
to include our sample data:
import React from 'react'
import { Search, Mic } from 'lucide-react'
const sampleData = [
{
id: 1,
title: 'React Official Documentation',
url: 'https://reactjs.org/',
},
{
id: 2,
title: 'Mozilla Developer Network (MDN)',
url: 'https://developer.mozilla.org/',
},
{
id: 3,
title: 'Stack Overflow',
url: 'https://stackoverflow.com/',
},
{
id: 4,
title: 'GitHub',
url: 'https://github.com/',
},
{
id: 5,
title: 'npm',
url: 'https://www.npmjs.com/',
},
]
const GoogleSearchBar = () => {
// Component code will go here
}
export default GoogleSearchBar
Step 4: Implement the Search State and Results
Update GoogleSearchBar.jsx
to include state and the debounce function.
We use a debouncer to trigger the search after a short delay when the user stops typing, rather than on every keystroke.
import React, { useState, useCallback, useEffect } from 'react'
import { Search, Mic } from 'lucide-react'
const sampleData = [
{
id: 1,
title: 'React Official Documentation',
url: 'https://reactjs.org/',
},
{
id: 2,
title: 'Mozilla Developer Network (MDN)',
url: 'https://developer.mozilla.org/',
},
{
id: 3,
title: 'Stack Overflow',
url: 'https://stackoverflow.com/',
},
{
id: 4,
title: 'GitHub',
url: 'https://github.com/',
},
{
id: 5,
title: 'npm',
url: 'https://www.npmjs.com/',
},
]
const GoogleSearchBar = () => {
// Todo for you: Add the below code to the GoogleSearchBar component:
const [searchTerm, setSearchTerm] = useState('')
const [searchResults, setSearchResults] = useState([])
const debounce = (func, delay) => {
let timeoutId
return (...args) => {
clearTimeout(timeoutId)
timeoutId = setTimeout(() => func(...args), delay)
}
}
// More code will be added here
}
export default GoogleSearchBar
Step 5: Create the Search Handler
Add the search handler to GoogleSearchBar.jsx
:
import React, { useState, useCallback, useEffect } from 'react'
import { Search, Mic } from 'lucide-react'
const sampleData = [
{
id: 1,
title: 'React Official Documentation',
url: 'https://reactjs.org/',
},
{
id: 2,
title: 'Mozilla Developer Network (MDN)',
url: 'https://developer.mozilla.org/',
},
{
id: 3,
title: 'Stack Overflow',
url: 'https://stackoverflow.com/',
},
{
id: 4,
title: 'GitHub',
url: 'https://github.com/',
},
{
id: 5,
title: 'npm',
url: 'https://www.npmjs.com/',
},
]
const GoogleSearchBar = () => {
const [searchTerm, setSearchTerm] = useState('')
const [searchResults, setSearchResults] = useState([])
const debounce = (func, delay) => {
let timeoutId
return (...args) => {
clearTimeout(timeoutId)
timeoutId = setTimeout(() => func(...args), delay)
}
}
// Todo for you: Add the below code to the GoogleSearchBar component:
const handleSearch = useCallback(
debounce((term) => {
if (term.trim() === '') {
setSearchResults([])
} else {
const results = sampleData.filter((item) =>
item.title.toLowerCase().includes(term.toLowerCase()),
)
setSearchResults(results)
}
}, 300),
[],
)
useEffect(() => {
handleSearch(searchTerm)
}, [searchTerm, handleSearch])
const handleInputChange = (e) => {
setSearchTerm(e.target.value)
}
// JSX will be added here
}
export default GoogleSearchBar
Step 6: Build the Component JSX
Complete the GoogleSearchBar.jsx
component by adding the JSX:
import React, { useState, useCallback, useEffect } from 'react'
import { Search, Mic } from 'lucide-react'
const sampleData = [
{
id: 1,
title: 'React Official Documentation',
url: 'https://reactjs.org/',
},
{
id: 2,
title: 'Mozilla Developer Network (MDN)',
url: 'https://developer.mozilla.org/',
},
{
id: 3,
title: 'Stack Overflow',
url: 'https://stackoverflow.com/',
},
{
id: 4,
title: 'GitHub',
url: 'https://github.com/',
},
{
id: 5,
title: 'npm',
url: 'https://www.npmjs.com/',
},
]
const GoogleSearchBar = () => {
const [searchTerm, setSearchTerm] = useState('')
const [searchResults, setSearchResults] = useState([])
const debounce = (func, delay) => {
let timeoutId
return (...args) => {
clearTimeout(timeoutId)
timeoutId = setTimeout(() => func(...args), delay)
}
}
const handleSearch = useCallback(
debounce((term) => {
if (term.trim() === '') {
setSearchResults([])
} else {
const results = sampleData.filter((item) =>
item.title.toLowerCase().includes(term.toLowerCase()),
)
setSearchResults(results)
}
}, 300),
[],
)
useEffect(() => {
handleSearch(searchTerm)
}, [searchTerm, handleSearch])
const handleInputChange = (e) => {
setSearchTerm(e.target.value)
}
// Todo for you: Add the below code to the GoogleSearchBar component:
return (
<div className="flex min-h-screen flex-col items-center bg-white p-4">
<form
onSubmit={(e) => e.preventDefault()}
className="mb-8 w-full max-w-2xl"
>
<div className="relative">
<input
type="text"
value={searchTerm}
onChange={handleInputChange}
className="w-full rounded-full border border-gray-200 bg-white px-5 py-3 pr-20 text-base shadow-md transition-shadow duration-200 hover:shadow-lg focus:border-gray-300 focus:outline-none"
placeholder="Search Google or type a URL"
/>
<div className="absolute right-0 top-0 mr-4 mt-3 flex items-center">
<button
type="button"
className="mr-3 text-gray-400 hover:text-gray-600"
onClick={() =>
alert(
'Voice search is unsupported in this demo.\nTry implementing this feature yourself π',
)
}
>
<Mic size={20} />{' '}
</button>{' '}
<button type="submit" className="text-blue-500 hover:text-blue-600">
<Search size={20} />{' '}
</button>{' '}
</div>{' '}
</div>{' '}
</form>{' '}
{searchResults.length > 0 && (
<div className="w-full max-w-2xl rounded-lg bg-white p-4 shadow-md">
<h2 className="mb-4 text-xl font-bold"> Search Results: </h2>{' '}
<ul>
{' '}
{searchResults.map((result) => (
<li key={result.id} className="mb-2">
<a
href={result.url}
className="text-blue-600 hover:underline"
target="_blank"
rel="noopener noreferrer"
>
{' '}
{result.title}{' '}
</a>{' '}
</li>
))}{' '}
</ul>{' '}
</div>
)}{' '}
</div>
)
}
export default GoogleSearchBar
Step 7: Add Tailwind CSS for styling
- Install Tailwind CSS: In your google-search-bar directory, run:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
You should now have a tailwind.config.js
file in your project root.
Note: Ensure that you're in the google-search-bar directory when you run these commands. Otherwise tailwind will be installed in the wrong directory, and it won't style your components.
- Configure your
tailwind.config.js
: Paste the following code into yourtailwind.config.js
file:
module.exports = {
content: ['./src/**/*.{js,jsx,ts,tsx}'],
theme: {
extend: {},
},
plugins: [],
}
- Add Tailwind directives to your CSS:
In your
src/index.css
file, replace the existing code with the following:
@tailwind base;
@tailwind components;
@tailwind utilities;
Step 8: Use the Component
Update your App.jsx
(in google-search-bar/src
) to use the GoogleSearchBar component. Paste the following code:
import React from 'react'
import GoogleSearchBar from './GoogleSearchBar'
function App() {
return (
<div className="App">
<GoogleSearchBar />
</div>
)
}
export default App
Step 9: Run Your Application
- Start your React application:
npm run dev
- Open your browser and navigate to
http://localhost:5173
to see your Google-style search bar in action!
Congratulations! You've created a Google-style search bar in React with sample data.
Next steps:
- Connect your search bar to a real API. It would be fun to connect this to the Bing search API directly, or your custom backend, perhaps using Django Ninja