티스토리 뷰

반응형

GatsbyJS에서 검색 기능 추가하기: Algolia와 Lunr.js 활용

웹사이트의 콘텐츠가 많아질수록 사용자가 원하는 정보를 빠르게 찾을 수 있도록 검색 기능이 필요합니다.
이번 글에서는 Gatsby에서 검색 기능을 추가하는 방법을 단계별로 설명하겠습니다. 🚀


1. Gatsby에서 검색 기능을 구현하는 방법

검색 기능 구현 방식 비교

방식 설명 사용 예시

클라이언트 측 검색 (Lunr.js) Gatsby에서 직접 인덱스를 생성하여 검색 블로그, 문서 사이트
서버 측 검색 (Algolia) 외부 검색 API를 사용하여 검색 결과 반환 대규모 콘텐츠 사이트
GraphQL 기반 검색 Gatsby의 GraphQL을 활용하여 필터링 소규모 데이터 검색

🚀 이번 글에서는 Gatsby에서 Lunr.js와 Algolia를 활용하여 검색 기능을 구현하는 방법을 다룹니다.


2. Lunr.js를 활용한 클라이언트 측 검색 기능 구현

Lunr.js는 작은 규모의 블로그나 문서 사이트에서 빠른 검색을 지원하는 라이브러리입니다.
👉 Gatsby에서 정적인 JSON 검색 인덱스를 생성하여 클라이언트에서 검색을 수행합니다.

Lunr.js 설치

npm install lunr

검색 인덱스 생성 (gatsby-node.js 설정 추가)

반응형

Gatsby는 GraphQL 데이터를 기반으로 검색 인덱스를 생성할 수 있습니다.

📌 gatsby-node.js 수정

const path = require("path");

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions;
  const blogTemplate = path.resolve("src/templates/blog-template.js");

  const result = await graphql(`
    query {
      allMarkdownRemark {
        nodes {
          frontmatter {
            slug
            title
          }
          excerpt
          rawMarkdownBody
        }
      }
    }
  `);

  const posts = result.data.allMarkdownRemark.nodes;

  // JSON 검색 인덱스 생성
  const searchIndex = posts.map(post => ({
    slug: post.frontmatter.slug,
    title: post.frontmatter.title,
    content: post.rawMarkdownBody,
  }));

  // JSON 파일 생성
  createPage({
    path: "/search-index.json",
    component: path.resolve("src/templates/empty.js"), // 빈 템플릿
    context: { searchIndex: JSON.stringify(searchIndex) },
  });

  // 블로그 글 페이지 생성
  posts.forEach(post => {
    createPage({
      path: `/blog/${post.frontmatter.slug}/`,
      component: blogTemplate,
      context: { slug: post.frontmatter.slug },
    });
  });
};

설명

  • allMarkdownRemark을 사용하여 모든 블로그 글 데이터를 가져옴
  • 검색을 위한 JSON 데이터(/search-index.json)를 생성

검색 컴포넌트 (src/components/Search.js) 추가

이제 Lunr.js를 활용하여 검색 기능을 구현합니다.

📌 Search.js 코드

import React, { useState, useEffect } from "react";
import lunr from "lunr";

const Search = () => {
  const [query, setQuery] = useState("");
  const [results, setResults] = useState([]);
  const [index, setIndex] = useState(null);

  useEffect(() => {
    fetch("/search-index.json")
      .then(res => res.json())
      .then(data => {
        const idx = lunr(function () {
          this.ref("slug");
          this.field("title");
          this.field("content");

          data.forEach(doc => this.add(doc));
        });
        setIndex(idx);
      });
  }, []);

  const search = event => {
    const query = event.target.value;
    setQuery(query);
    if (!index) return;
    const searchResults = index.search(query).map(({ ref }) => data.find(doc => doc.slug === ref));
    setResults(searchResults);
  };

  return (
    <div>
      <input type="text" value={query} onChange={search} placeholder="검색어 입력..." />
      <ul>
        {results.map(post => (
          <li key={post.slug}>
            <a href={`/blog/${post.slug}/`}>{post.title}</a>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default Search;

🚀 이제 검색 입력창에 키워드를 입력하면 블로그 글이 검색됩니다.


3. Algolia를 활용한 고급 검색 기능 추가

대규모 콘텐츠를 검색하려면 Algolia를 사용하여 빠른 검색 결과를 제공할 수 있습니다.

Algolia 플러그인 설치

npm install gatsby-plugin-algolia

Algolia 계정 및 API 키 설정

  1. Algolia에 가입앱을 생성
  2. API 키를 발급받아 gatsby-config.js에 추가

📌 gatsby-config.js 설정

const queries = [
  {
    query: `
      {
        allMarkdownRemark {
          nodes {
            frontmatter {
              title
              slug
            }
            excerpt
          }
        }
      }
    `,
    transformer: ({ data }) =>
      data.allMarkdownRemark.nodes.map(post => ({
        objectID: post.frontmatter.slug,
        title: post.frontmatter.title,
        excerpt: post.excerpt,
        slug: post.frontmatter.slug,
      })),
    indexName: "gatsby_blog",
  },
];

module.exports = {
  plugins: [
    {
      resolve: `gatsby-plugin-algolia`,
      options: {
        appId: "YOUR_ALGOLIA_APP_ID",
        apiKey: "YOUR_ALGOLIA_ADMIN_API_KEY",
        queries,
      },
    },
  ],
};

Algolia에 데이터 업로드 (gatsby build 실행)

GATSBY_ALGOLIA_APP_ID=YOUR_ALGOLIA_APP_ID \
GATSBY_ALGOLIA_SEARCH_KEY=YOUR_ALGOLIA_SEARCH_KEY \
npm run build

설명

  • Gatsby가 빌드될 때 블로그 데이터를 Algolia 인덱스로 업로드

Algolia 검색 컴포넌트 (src/components/AlgoliaSearch.js)

📌 Algolia 검색 기능 추가

import React, { useState } from "react";
import algoliasearch from "algoliasearch/lite";
import { InstantSearch, SearchBox, Hits } from "react-instantsearch-hooks-web";

const searchClient = algoliasearch("YOUR_ALGOLIA_APP_ID", "YOUR_ALGOLIA_SEARCH_KEY");

const Hit = ({ hit }) => (
  <div>
    <a href={`/blog/${hit.slug}/`}>
      <h3>{hit.title}</h3>
      <p>{hit.excerpt}</p>
    </a>
  </div>
);

const AlgoliaSearch = () => {
  return (
    <InstantSearch searchClient={searchClient} indexName="gatsby_blog">
      <SearchBox />
      <Hits hitComponent={Hit} />
    </InstantSearch>
  );
};

export default AlgoliaSearch;

🚀 이제 블로그 검색창에서 실시간으로 검색 결과를 확인할 수 있습니다!


4. 결론

이번 글에서는 GatsbyJS에서 검색 기능을 추가하는 다양한 방법을 배웠습니다.
Lunr.js를 활용한 정적 JSON 기반 클라이언트 검색
Algolia를 활용한 대규모 데이터 검색
GraphQL을 사용하여 검색 인덱스 생성

🚀 다음 글에서는 GatsbyJS에서 페이지네이션(Pagination) 기능을 추가하는 방법을 다루겠습니다!

 

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함
반응형