Add full-text search with Chinese tokenization using Pagefind

Integrated Pagefind for static site search with built-in Chinese word segmentation support.

Changes:
1. **Installed Pagefind** (v1.4.0) as dev dependency
2. **Updated build script** to run Pagefind indexing after Next.js build
   - Indexes all 69 pages with 5,711 words
   - Automatic Chinese (zh-tw) language detection
3. **Created search modal component** (components/search-modal.tsx)
   - Dynamic Pagefind UI loading (lazy-loaded on demand)
   - Keyboard shortcuts (Cmd+K / Ctrl+K)
   - Chinese translations for UI elements
   - Dark mode compatible styling
4. **Added search button to header** (components/site-header.tsx)
   - Integrated SearchButton with keyboard shortcut display
   - Modal state management
5. **Custom Pagefind styles** (styles/globals.css)
   - Tailwind-based styling to match site design
   - Dark mode support
   - Highlight styling for search results

Features:
-  Full-text search across all blog posts and pages
-  Built-in Chinese word segmentation (Unicode-based)
-  Mixed Chinese/English query support
-  Zero bundle impact (20KB lazy-loaded on search activation)
-  Keyboard shortcuts (⌘K / Ctrl+K)
-  Search result highlighting with excerpts
-  Dark mode compatible

Technical Details:
- Pagefind runs post-build to index .next directory
- Search index stored in .next/pagefind/
- Chinese segmentation works automatically via Unicode boundaries
- No third-party services or API keys required

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-20 00:10:26 +08:00
parent 912c70332e
commit 2c9d5ed650
5 changed files with 339 additions and 2 deletions

104
package-lock.json generated
View File

@@ -38,6 +38,7 @@
"concurrently": "^9.2.1",
"eslint": "^9.39.1",
"eslint-config-next": "^16.0.3",
"pagefind": "^1.4.0",
"postcss": "^8.5.6",
"tailwindcss": "^3.4.18",
"typescript": "^5.9.3"
@@ -2489,6 +2490,90 @@
"node": ">=14"
}
},
"node_modules/@pagefind/darwin-arm64": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@pagefind/darwin-arm64/-/darwin-arm64-1.4.0.tgz",
"integrity": "sha512-2vMqkbv3lbx1Awea90gTaBsvpzgRs7MuSgKDxW0m9oV1GPZCZbZBJg/qL83GIUEN2BFlY46dtUZi54pwH+/pTQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@pagefind/darwin-x64": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@pagefind/darwin-x64/-/darwin-x64-1.4.0.tgz",
"integrity": "sha512-e7JPIS6L9/cJfow+/IAqknsGqEPjJnVXGjpGm25bnq+NPdoD3c/7fAwr1OXkG4Ocjx6ZGSCijXEV4ryMcH2E3A==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@pagefind/freebsd-x64": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@pagefind/freebsd-x64/-/freebsd-x64-1.4.0.tgz",
"integrity": "sha512-WcJVypXSZ+9HpiqZjFXMUobfFfZZ6NzIYtkhQ9eOhZrQpeY5uQFqNWLCk7w9RkMUwBv1HAMDW3YJQl/8OqsV0Q==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
]
},
"node_modules/@pagefind/linux-arm64": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@pagefind/linux-arm64/-/linux-arm64-1.4.0.tgz",
"integrity": "sha512-PIt8dkqt4W06KGmQjONw7EZbhDF+uXI7i0XtRLN1vjCUxM9vGPdtJc2mUyVPevjomrGz5M86M8bqTr6cgDp1Uw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@pagefind/linux-x64": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@pagefind/linux-x64/-/linux-x64-1.4.0.tgz",
"integrity": "sha512-z4oddcWwQ0UHrTHR8psLnVlz6USGJ/eOlDPTDYZ4cI8TK8PgwRUPQZp9D2iJPNIPcS6Qx/E4TebjuGJOyK8Mmg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
]
},
"node_modules/@pagefind/windows-x64": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@pagefind/windows-x64/-/windows-x64-1.4.0.tgz",
"integrity": "sha512-NkT+YAdgS2FPCn8mIA9bQhiBs+xmniMGq1LFPDhcFn0+2yIUEiIG06t7bsZlhdjknEQRTSdT7YitP6fC5qwP0g==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@@ -4880,6 +4965,7 @@
"integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@rtsao/scc": "^1.1.0",
"array-includes": "^3.1.9",
@@ -8559,6 +8645,24 @@
"dev": true,
"license": "BlueOak-1.0.0"
},
"node_modules/pagefind": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/pagefind/-/pagefind-1.4.0.tgz",
"integrity": "sha512-z2kY1mQlL4J8q5EIsQkLzQjilovKzfNVhX8De6oyE6uHpfFtyBaqUpcl/XzJC/4fjD8vBDyh1zolimIcVrCn9g==",
"dev": true,
"license": "MIT",
"bin": {
"pagefind": "lib/runner/bin.cjs"
},
"optionalDependencies": {
"@pagefind/darwin-arm64": "1.4.0",
"@pagefind/darwin-x64": "1.4.0",
"@pagefind/freebsd-x64": "1.4.0",
"@pagefind/linux-arm64": "1.4.0",
"@pagefind/linux-x64": "1.4.0",
"@pagefind/windows-x64": "1.4.0"
}
},
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",