종속성 없이 몇 분 만에 웹사이트에 대한 가장 빠른 검색을 생성하세요 ⚡🔎
Jump to main content
The project I'm working on is written in Gatsby JS, but the solution itself is vanilla react and will work everywhere.
오늘 저는 my blog 업데이트에 대부분의 시간을 할애했으며 검색, 태그, MDX 지원 및 사이드바를 포함한 몇 가지 디자인 변경과 같은 더 많은 기능을 추가할 생각을 했습니다.
검색 기능을 구현하는 방법을 결정하고 있었습니다. 검색 기능을 수행한 유일한 시간은
Typesense의 자체 호스팅 버전
하지만 음, 서버 측을 호스트하는 데 비용이 많이 들었습니다.
블로그처럼 단순한 것. 호스팅 솔루션도 가격면에서 그다지 좋지 않습니다.
따라서 한 가지 확실한 것은 이를 위해 API를 사용할 필요가 없다는 것입니다. 빠른 Google 검색 후 Gatsby의 웹사이트에서 adding search to Gatsby에 관한 이 문서를 발견했습니다.
해당 가이드의
Client Side
섹션에서 권장 사항은 다음과 같습니다.타사 솔루션 없이도 Gatsby 사이트에서 모든 작업을 수행할 수 있습니다. 여기에는 약간의 코드 작성이 포함되지만 더 적은 서비스를 사용합니다. 인덱싱할 콘텐츠가 많으면 번들 크기도 크게 증가할 수 있습니다.
이를 수행하는 한 가지 방법은 js-search 라이브러리를 사용하는 것입니다.
Adding Search with JS Search
이를 지원하는 두 개의 Gatsby 플러그인이 있습니다.
gatsby-plugin-elasticlunr-search
gatsby-plugin-local-search
이제 이러한 검색 방법은 더 큰 번들 크기를 의미하는 모든 것을 인덱싱합니다. 그리고 그들은 또한 설정하기 번거롭습니다.
내가 함께 갔던 솔루션
Now for my use case, it was probably a good idea to just make something simple by myself, and I can build on it as I keep updating this blog.
The idea is really simple, I just need to make a search box, and on every keystroke, loop through the contents and filter them like that.
const BlogIndex = ({ data, location }) => {
// These posts can be anything,
// I've just used the posts from a gatsby query
const posts = data.allMdx.edges;
// We need to filter the posts by the search query.
// by default, we have all posts
const [filteredPosts, setFilteredPosts] = useState(posts);
// This will be the search query
const [search, setSearch] = useState('');
return (
<div>
{/* Our search bar */}
<input
type="text"
placeholder="Search"
onChange={(e) => {
e.preventDefault();
setSearch(e.target.value)}
}/>
{/* Simply mapping through everything and rendering blogs */}
{filteredPosts.map(({ node }) => {
<BlogPost post={node} key={node.id} />
}}
</div>
)
}
Now, whenever something is typed in the box, the search
state will be updated. Now, let's write a useEffect
hook to update the filteredPosts
state whenever the search
state changes.
const BlogIndex = ({ data, location }) => {
const posts = data.allMdx.edges;
const [filteredPosts, setFilteredPosts] = useState(posts);
const [search, setSearch] = useState('');
//highlight-start
useEffect(() => {
if (search) {
// post filtering here
}
}
// only update the filteredPosts state when the search state changes or the posts state changes
, [search, posts]);
///highlight-end
return (
... // rest of the code
)
And now let's write some very simple code to filter the posts.
...
if (search) {
const filteredPosts = posts.filter(post => {
//highlight-start
const title = post.title.toLowerCase();
const description = post.description.toLowerCase();
return title.match(search.toLowerCase()) || description.match(search.toLowerCase());
//highlight-end
}
}
setFilteredPosts(filteredPosts);
...
Since my blog has tags and stuff like that, I added functionality to search and filter by tags, too
if (search.startsWith("#")) {
return tags.includes(search.replace("#", ""));
}
...
공유해야 할 때 더 쉽고 편리하기 때문에 그게 좀 중요하다고 생각합니다.
그럼 실시간으로 검색어를 포함하도록 URL을 업데이트하겠습니다. 나는 전에 이것을 해본 적이 없었기 때문에 그것을 배우는 것이 좋았습니다. IFTTT search engine에서 영감을 얻었습니다.
기본적으로 브라우저 기록에 추가하거나 페이지를 다시 로드하지 않고 새 URL을 푸시할 수 있는
window.history.pushState()
방법에 대해 알게 되었습니다. 여기에서 동일한 문서를 읽으십시오 -History API | MDN
useEffect(() => {
if (search) {
//highlight-start
if (window.history.pushState) {
window.history.pushState(null, null, `/?q=${search}`);
}
//highlight-end
const filteredPosts = posts.filter(post => {
const title = post.title.toLowerCase();
const description = post.description.toLowerCase();
return title.match(search.toLowerCase()) || description.match(search.toLowerCase());
}
}
setFilteredPosts(filteredPosts);
}, [search]);
이제
window location
개체를 사용하여 원래 요청을 구문 분석하고 useState
에 대해 만든 search
후크의 기본값으로 설정해야 합니다. // 👇🏻 converts the URL from HTML encoded to a string (%20 to space)
const initialState = decodeURI(location.href? // Use window location
.split('/') // Split the URL into an array
.pop() // Get the last element only
.split("=") // at this point, it's q=search, so we only need the "Search" parth
.pop() );
// 👇🏻 We're using the initialState to set the search query.
const [search, setSearch] = useState(initialState); // Now, only the blogs that match the query will be displayed on first load
그게 다야!
전체 구현은 source code of this blog on Github에서 찾을 수 있습니다.
당신은 할 수 있습니다
여기에서 이 블로그의 저장소를 자유롭게 방문하세요.
Reference
이 문제에 관하여(종속성 없이 몇 분 만에 웹사이트에 대한 가장 빠른 검색을 생성하세요 ⚡🔎), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/dhravya/create-the-fastest-search-for-your-website-in-minutes-without-any-dependencies-56me텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)