In this section we will see create search bar in nextjs 13 with tailwind css. We will see search bar with search icon, search with fake api example nextjs 13 with tailwind css.
Install Tailwind CSS In NextJS 13
Tool Use
Tailwind CSS 3.x
NextJS 13
Heroicons Icon
Example 1
Nextjs with tailwind css search bar with heroicons svg icon left side and right side.
export default function Home() {
return (
<div className="flex flex-col items-center justify-center min-h-screen">
<div className="flex items-center justify-center">
<div className="flex border-2 rounded">
<input
type="text"
className="px-4 py-2 w-80"
placeholder="Search..."
/>
<button className="flex items-center justify-center px-4 border-l">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="w-6 h-6 text-gray-600"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
/>
</svg>
</button>
</div>
</div>
<div className="mt-12">
<div className="flex border-2 rounded">
<button className="flex items-center justify-center px-4 border-r">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
className="w-6 h-6 text-gray-600"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
/>
</svg>
</button>
<input
type="text"
className="px-4 py-2 w-80"
placeholder="Search..."
/>
</div>
</div>
</div>
);
}
Example 2
Nextjs with tailwind css responsive search using useState hook.
import { useState } from "react";
export default function Home() {
const [searchTerm, setSearchTerm] = useState("");
const handleSearch = (event) => {
setSearchTerm(event.target.value);
console.log(`Searching for ${searchTerm}`);
};
return (
<div className="container mx-auto mt-20">
<div className="flex flex-col items-center justify-center">
<div className="">
<input
type="text"
value={searchTerm}
onChange={handleSearch}
className="w-full h-10 px-4 pr-10 text-sm bg-white border border-gray-300 rounded-lg lg:w-80 focus:outline-none"
placeholder="Search term..."
/>
</div>
{searchTerm && (
<div className="mt-10 text-2xl">Search term: {searchTerm}</div>
)}
</div>
</div>
);
}
Example 3
Nextjs with tailwind css search books dummy data using useState hook.
import { useState } from "react";
const books = [
{ id: 1, title: "Moby Dick", author: "Herman Melville" },
{ id: 2, title: "The Great Gatsby", author: "F. Scott Fitzgerald" },
{ id: 3, title: "To Kill a Mockingbird", author: "Harper Lee" },
];
export default function Home() {
const [searchTerm, setSearchTerm] = useState("");
const [searchResults, setSearchResults] = useState([]);
const handleSearch = (event) => {
setSearchTerm(event.target.value);
if (event.target.value !== "") {
const results = books.filter((book) =>
book.title.toLowerCase().includes(event.target.value.toLowerCase())
);
setSearchResults(results);
} else {
setSearchResults([]);
}
};
return (
<div className="flex flex-col items-center justify-center min-h-screen py-2">
<div className="w-full max-w-md">
<div className="flex mt-10 border-2 border-gray-300 rounded-lg">
<input
type="text"
value={searchTerm}
onChange={handleSearch}
className="w-full px-4 py-2 text-sm focus:outline-none"
placeholder="Search books..."
/>
<button className="flex items-center justify-center px-4 bg-gray-300">
<svg
className="w-6 h-6 text-gray-500"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
/>
</svg>
</button>
</div>
</div>
{searchResults.map((book) => (
<div key={book.id} className="mt-10 text-xl">
Title: {book.title}, Author: {book.author}
</div>
))}
</div>
);
}
Example 4
Nextjs with tailwind css search fake api data using useState and useEffect hook.
import { useState, useEffect } from "react";
export default function Home() {
const [searchTerm, setSearchTerm] = useState("");
const [posts, setPosts] = useState([]);
const [filteredPosts, setFilteredPosts] = useState([]);
useEffect(() => {
const fetchPosts = async () => {
const response = await fetch(
"https://jsonplaceholder.typicode.com/posts"
);
const data = await response.json();
setPosts(data);
};
fetchPosts();
}, []);
useEffect(() => {
if (searchTerm !== "") {
const results = posts.filter((post) =>
post.title.toLowerCase().includes(searchTerm.toLowerCase())
);
setFilteredPosts(results);
} else {
setFilteredPosts([]);
}
}, [searchTerm, posts]);
const handleSearch = (event) => {
setSearchTerm(event.target.value);
};
return (
<div className="flex flex-col items-center justify-center min-h-screen py-2">
<div className="w-full max-w-md">
<div className="flex mt-10 rounded-lg">
<input
type="text"
value={searchTerm}
onChange={handleSearch}
className="w-full px-4 py-2 text-sm focus:outline-none"
placeholder="Search posts..."
/>
<button className="flex items-center justify-center px-4 bg-blue-500">
<svg
className="w-6 h-6 text-white"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
/>
</svg>
</button>
</div>
</div>
{searchTerm &&
filteredPosts.map((post) => (
<div key={post.id} className="mt-10 text-lg">
<p>
<strong>Title:</strong> {post.title}
</p>
<p>
<strong>Body:</strong> {post.body}
</p>
</div>
))}
</div>
);
}