v2.8.2

Search

minista には全文検索をサポートする 2 つの機能が備わっています。一つは HTML を解析してインデックス化された JSON を生成する機能。もう一つは JSON をもとに検索する React Component。

HTML と出力される JSON の関係は以下の通りです。

<!-- dist/docs/css.html -->
<head>
  <title>CSS</title>
</head>
<body>
  <h1>CSS</h1>
  <div data-search>
    <h2 id="cms">CMS</h2>
    <p>CMSで使うCSS。</p>
  </div>
</body>
// dist/assets/search.json
{
  "words": ["CMS", "CSS", "。", "う", "で", "使"],
  "hits": [0, 1],
  "pages": [
    {
      "path": "/docs/css",
      "title": [1],
      "toc": [[0, "cms"]],
      "content": [0, 0, 4, 5, 3, 1, 2]
    }
  ]
}
  • words にすべての文字が種類ごとに収納されており index で参照が可能
  • hits[0, 1] なので、検索対象の文字は「CMS」と「CSS」
  • pages は各ページデータ(title は「CSS」、見出し ID cms の content は 0 番目)
  • content には「CMS CMS で使う CSS。」の index が配列形式で格納

Build JSON

まずは Configsearch.useJsontrue にしてください。これを設定すると開発時・本番ビルドで JSON が生成されます。デフォルト値は以下の通りです。サイトに合わせて必要な部分を調整します。

{
  search: {
    useJson: false, // boolean
    cache: false, // boolean
    outDir: "assets", // string
    outName: "search", // string
    include: ["**/*"], // string[]
    exclude: ["404"], // string[]
    trimTitle: "", // string
    targetSelector: "[data-search]", // string
    hit: {
      minLength: 3, // number
      number: false, // boolean
      english: true, // boolean
      hiragana: false, // boolean
      katakana: true, // boolean
      kanji: true, // boolean
    },
  },
}

cache

true にすると、前回作った JSON を再利用します。※開発時のみ

include

検索対象にしたいディレクトリやファイルを配列と glob 形式を使って設定できます。デフォルトの ["**/*"] はすべてのページが検索対象になりますので ["posts/**/*"] などで絞り込むことをお勧めします。

exclude

検索対象から省きたいディレクトリやファイルを配列と glob 形式を使って設定できます。

trimTitle

検索したページのタイトルから任意の文字列を削除します。主にサイトタイトルを消す用途で使います。

targetSelector

検索対象ページのインデックス化するセレクターを設定します。

hit

検索にヒットする単語の最低文字数 minLength や、ヒットする文字の種類を設定します。

Built-in Component

検索用のコンポーネント <Search /> が同封されているので生成した JSON をすぐに使えます。

CAUTION

  • <Search /> は Partial Hydration 化した場所でのみ使えます
  • 固有のスタイルは付属していません(試用 CSS

まずは、ページかコンポーネントのどこかで Partial Hydration の場所を作り、その中で <Search /> を使います。jsonPath が必須で search.json の場所を入力します。

// src/pages/index.tsx
import BlockSearch from "../components/block-search?ph"

export default () => {
  return <BlockSearch />
}
// src/components/block-search.tsx
import { Search } from "minista"

export default () => {
  return (
    <Search
      jsonPath="/assets/search.json"
      placeholder="Search..."
      className="block-search"
      searchFieldClassName="block-search-field"
      searchListClassName="block-search-list"
    />
  )
}