Gatsby 블로그에 검색 기능을 추가하기 (with Gatsby-starter-bee )

thumbnail

블로그를 갈아타면서…

기존에 쓰던 Hexo 를 버리고 새롭게 이전을 했다.
개인적으로 만들던 플젝에 집중하느라 블로그 이전이 좀 늦었었다.

자잘한 이야기는 뒤로 하고…
Gatsby로 갈아타면서 직접 블로그를 만들까 했는데 할일이 너무 많아서 포기했다.
사실 직장 안다니면 한가할 줄 알았는데 전혀…
할일이 더 많아진거 같다. =.=

그래서 직접 개발은 포기하고 다른거 주워서 쓰려고 찾아보니…
이 블로그 테마가 가장 많이 사용되는거 같았다. Gatsby-starter-bee

근데 이 테마의 단점(?)은 검색 기능이 없다는 것이다.
그래서 깃허브 이슈에도 등록이 되어는 있지만,
진척은 없었다.

그래도 마지막에 kostyrko라는 외국 성님이 뭔가 힌트를 줘서 나도 그거에 맞춰 적용을 해봤다.

이 내용은 내 블로그에 검색 기능을 추가하는 것을 남길 목적으로 포스팅한다.

다른 테마 버그나 기타 문의는 깃허브 이슈 등록을 하고 물어보길 바란다.
(여담인데 요새는 업데이트가 안되고 버려진거 같다.)

진행에 앞서…
내가 사용하는 Node 버전은 14.15.0 버전이다.
아마 이 테마를 받아서 그대로 사용하는 사람은 저 버전이거나 근처일거라 생각한다.


1. npm 패키지 추가

package.json 파일에 아래의 dependencies 들을 추가하고 설치한다.

{
    ...
    "flexsearch": "^0.7.21",
    "gatsby-plugin-local-search": "^2.0.1",
    "react-use-flexsearch": "^0.1.1"
    ...
}

npm install


2. 파일 수정

크게 커스텀을 안했다는 가정하에 작성한다.
아래 코드를 복붙 하지 말고 주석을 참고해서 배치하자.

//pages/index.js 파일 수정

//import 추가
import { Search } from '../components/search'
import { useFlexSearch } from 'react-use-flexsearch'

//상단 getDistance 함수 근처 (또는 원하는 곳에...)
function unFlattenResults(results) {
  return results.map(post => {
    const { slug, excerpt, title, category, date, draft } = post
    return {
      node: {
        excerpt: excerpt,
        frontmatter: { title, category, date, draft },
        fields: { slug },
      },
    }
  })
}

//아래 상수 있는 부근에.. (이것도 원하는 곳에...)
//const { countOfInitialPost } = siteMetadata.configs

const isBrowser = () => typeof window !== 'undefined'
const { search } = isBrowser() && window.location

const query = new URLSearchParams(search).get('s')
const [searchQuery, setSearchQuery] = useState(query || '')
const results = useFlexSearch(
  searchQuery,
  data.localSearchPages.index,
  data.localSearchPages.store
)

const posts = searchQuery
  ? unFlattenResults(results)
  : data.allMarkdownRemark.edges

//기존에 사용하던 posts 상수는 주석 처리 해준다.
// const posts = data.allMarkdownRemark.edges

//하단에 graphql 부분에 다음과 같이 추가한다.
//localSearchPages 항목을 배치해준다.

export const pageQuery = graphql`
  query {
    localSearchPages {
      index
      store
    }
    site {}
    }`

3. 컴포넌트 추가

src 밑에 component 디렉토리에 search 디렉토리를 새로 만들고,
index.jsx index.scss 두 파일을 만들어준다.

그리고 아래와 같이 추가한다.

//src/component/search/index.jsx

import React from 'react'
import './index.scss'

export const Search = ({ searchQuery, setSearchQuery }) => {
  return (
    <form action="/" method="get" autoComplete="off" className="search-form">
      <label htmlFor="header-search">
        <span className="visually-hidden">Search blog posts</span>
      </label>
      <input
        value={searchQuery}
        onChange={e => setSearchQuery(e.target.value)}
        type="text"
        id="header-search"
        className="search-form__input"
        placeholder="Serch keyword"
        name="s"
      />
    </form>
  )
}
//src/component/search/index.scss

.search-form {
  width: 100%;
  display: flex;
  justify-content: center;
  .visually-hidden {
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    height: 1px;
    overflow: hidden;
    position: absolute;
    white-space: nowrap;
    width: 1px;
  }
  .search-form__input {
    font-family: Source Sans Pro, Roboto, Open Sans, Liberation Sans, DejaVu
        Sans, Verdana, Helvetica, Arial, sans-serif;
    outline: 0;
    margin: 0;
    border: 1px solid #d9d9d9;
    box-sizing: border-box;
    color: #333;
    display: block;
    font-size: 14px;
    height: 40px;
    line-height: 40px;
    padding: 0 15px;
    max-width: 350px;
    width: 90%;
    border-radius: 25px;
    background: #f5f5f5;
    box-shadow: inset 4px 4px 4px #d0d0d0;
  }
}

4. gatsby-config.js 파일 수정

gatsby-config.js 파일의 일부 수정하면 끝이다.

{
    ...
    {
      resolve: 'gatsby-plugin-local-search',
      options: {
        name: 'pages',
        engine: 'flexsearch',
        query: `
              query {
                allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }) {
                  nodes {
                    excerpt
                    fields {
                      slug
                    }
                    frontmatter {
                      date(formatString: "MMMM DD, YYYY")
                      title,
                      category
                    }
                  }
                }
              }
            `,
        ref: 'slug',
        index: ['title', 'excerpt', 'category'],
        store: ['title', 'excerpt', 'slug', 'date', 'category'],
        normalizer: ({ data }) =>
          data.allMarkdownRemark.nodes.map(node => ({
            title: node.frontmatter.title,
            excerpt: node.excerpt,
            slug: node.fields.slug,
            date: node.frontmatter.date,
            category: node.frontmatter.category,
          })),
      },
    },
    `gatsby-transformer-sharp`,
    ...
}

이렇게 하고 구동하면 내 블로그 처럼 검색 기능이 달릴거다.
나처럼 바쁜데 컨텐츠는 올려야 하고, 직접 구현은 시간이 없어서 대충 쓰고 싶은 사람들에겐 최고의 결과물 조합이 아닐까 싶다.

이렇게 했는데도 잘 모르겠고, 답답한 분들은 댓글 또는 이 깃허브(kostyrko) 를 참고하자.
이 형님이 아까 이슈에서 참고했던 깃허브이다.
이거 보고도 적용이 안된다면…=.=;;;

그냥 다른 블로그 테마를 찾아보는 것이 정신적으로 편안할 듯 싶다.


PS : 시간이 부족하다…


Written by@MHLab
로또는 흑우집합소 🎲
와인관리, 시음노트, 셀러관리는 마와셀 🥂

🫥 My Service|  📜 Contact|  💻 GitHub