Takazudo Modular Docs

Type to search...

to open search from anywhere

Search

Full-text search architecture using MiniSearch

Search

Full-text search over site content using MiniSearch. The search index is generated at build time from MDX content files.

Architecture

flowchart TB
    subgraph Build Time
        MDX["MDX files<br/>(products, guides, notes, highlights, s)"] --> Script["generate-search-index.mjs"]
        Script --> SearchJSON["search-index.json<br/>(included in dist/)"]
        Script --> FunctionsJSON["netlify/functions/search-data.json"]
    end

    subgraph Production
        Browser -->|"GET /api/search?q=..."| NetlifyFn["Netlify Function<br/>(search.ts)"]
        NetlifyFn --> FunctionsJSON
    end

    subgraph Development
        Browser2["Browser"] -->|"fetch /search-index.json"| ClientSearch["Client-side MiniSearch"]
        ClientSearch --> SearchJSON
    end

Production Mode

In production, search requests go to the Netlify Function search.ts which loads the pre-built search index and runs MiniSearch server-side. Results include highlighted titles and excerpts.

Development Mode

In development, the search runs entirely client-side. The search component fetches /search-index.json and creates a MiniSearch instance in the browser. This avoids needing to run Netlify Functions locally for search.

Search Index Generation

Script: scripts/generate-search-index.mjs

Run manually:

node scripts/generate-search-index.mjs

This is also invoked during the build via pnpm build:search-index.

Content Sources

Content TypeDirectoryURL Prefix
Productssrc/mdx/products//products
Guidessrc/mdx/guides//guides
Highlightssrc/mdx/highlights//notes
Notessrc/mdx/notes//notes
Standalonesrc/mdx/s//s

Document Fields

Each document in the index contains:

FieldSourceIndexedStored
id{contentType}/{fileSlug}NoNo
slug{urlPrefix}/{routeSlug}/NoYes
titleFrontmatter titleYes (boost: 3)Yes
descriptionFrontmatter descriptionYes (boost: 2)Yes
tagsFrontmatter tags (space-joined)Yes (boost: 1.5)Yes
excerptFirst 500 chars of plain textYesYes
createdAtFrontmatter createdAtNoYes

EN Article Handling

EN articles use .en.mdx file extension. The index generator:

  • Uses fileSlug (with .en) for the document id to ensure uniqueness (e.g., guides/col007-power-vol3.en)
  • Uses routeSlug (without .en) for the URL slug (e.g., /guides/col007-power-vol3/)

This ensures JA and EN articles for the same content have unique IDs but share the same route slug.

Exclusions

  • Files starting with _ (fragments) are skipped
  • Files with avoidListing: true in frontmatter are skipped

Search Options

MiniSearch is configured with:

  • Prefix search: enabled (prefix: true)
  • Fuzzy matching: 0.2 edit distance (fuzzy: 0.2)
  • Field boosting: title (3x) > description (2x) > tags (1.5x) > excerpt (1x)

Keyword Logging

In production, the Netlify Function logs search keywords to Netlify Blobs (keyword-logs store) for analytics. Each entry includes:

  • keyword: the search query
  • timestamp: ISO 8601 timestamp
  • resultCount: number of results returned

Search UI

Pages

  • JA: /search/ (src/astro/pages/search.astro)
  • EN: /en/search/ (src/astro/pages/en/search.astro)

Components

  • components/search/search-page-content.tsx — main search page with input and results (React island)
  • components/search/search-result-item.tsx — individual result display

Output Files

FilePurposeGit tracked
public/search-index.jsonClient-side dev fallbackNo (gitignored)
netlify/functions/search-data.jsonNetlify Function bundle inputNo (gitignored)

Both are regenerated at build time and should not be committed.