@hutusi/amytis 1.5.6 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,94 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.6.0] - 2026-02-20
9
+
10
+ ### Added
11
+ - **Search Engine Upgrade**: Migrated from Fuse.js to **Pagefind** for high-performance, static full-text search with extremely low client-side overhead.
12
+ - **Enhanced Search UI**:
13
+ - Full-content search with context highlighting and excerpts.
14
+ - Type-based filtering tabs (All, Post, Flow, Book).
15
+ - Recent searches history persisted in local storage.
16
+ - Interactive search tips panel with syntax hints.
17
+ - Advanced keyboard navigation (Tab-based focus trap, arrow keys, Alt+number shortcuts).
18
+ - Debounced input and visual loading states.
19
+ - Full-screen responsive layout for mobile devices.
20
+ - **Search Utilities**: New unit-tested utility library for processing search results and metadata.
21
+ - **Project Documentation**: Added a comprehensive `CHANGELOG.md` documenting the project's evolution from 1.0.0.
22
+
23
+ ### Changed
24
+ - **Documentation Overhaul**: Streamlined `TODO.md` roadmap and updated `GEMINI.md` and `ARCHITECTURE.md` to reflect the new search architecture.
25
+ - **i18n**: Fully localized search interface supporting both English and Chinese.
26
+
27
+ ### Fixed
28
+ - **Hydration**: Suppressed body-level hydration warnings caused by browser extensions.
29
+ - **Search Precision**: Improved title cleaning and date extraction for search results.
30
+
31
+ ## [1.5.6] - 2026-02-19
32
+
33
+ ### Added
34
+ - **Scoped Publishing**: Transitioned to `@hutusi/amytis` for official release on npm and GitHub.
35
+ - **Trusted Publishing**: Implemented secure OIDC-based deployment for npm.
36
+ - **Engineering Quality**: Added `bun run validate` to integrate linting, testing, and building.
37
+
38
+ ### Changed
39
+ - **Refined DX**: Cleaned up all linting warnings and optimized interactive components with `requestAnimationFrame` cleanup.
40
+ - **Better Accessibility**: Improved `MarkdownRenderer` semantics by preserving native `<p>` tags.
41
+
42
+ ### Fixed
43
+ - **Hydration & Stability**: Resolved all React 19 hydration mismatches in `LanguageProvider`, `Hero`, and `ThemeToggle`.
44
+ - **Content Fixes**: Corrected mangled LaTeX formulas and resolved duplicated frontmatter mapping keys.
45
+
46
+ ## [1.5.0] - 2026-02-18
47
+
48
+ ### Added
49
+ - **Daily Notes (Flows)**: A new stream-style content format for micro-blogging and quick thoughts.
50
+ - **Full-text Search**: Migrated to **Pagefind** for high-performance static full-text indexing.
51
+ - **Metadata Inheritance**: Implemented logic for posts to inherit attributes from series metadata.
52
+
53
+ ### Changed
54
+ - **Major Tech Upgrade**: Modernized architecture to **Next.js 16 (App Router)** and **React 19**.
55
+ - **UI Overhaul**: Redesigned homepage with horizontal scroll featured sections and distinct card styles.
56
+ - **Austere Elegance**: New design for Archive and Tags pages focusing on minimalism.
57
+
58
+ ## [1.4.0] - 2026-02-10
59
+
60
+ ### Added
61
+ - **Books Feature**: Support for structured, multi-chapter long-form content.
62
+ - **Reading Progress**: Integrated sticky progress bar and scroll tracking.
63
+ - **Import Tooling**: New CLI commands for PDF and image folder ingestion.
64
+
65
+ ## [1.3.0] - 2026-02-05
66
+
67
+ ### Added
68
+ - **Internationalization (i18n)**: Native support for English and Chinese with language switching.
69
+ - **Smart Reading Time**: Multilingual character counting for accurate estimates.
70
+ - **Author Pages**: Detailed statistics and contribution tracking.
71
+
72
+ ## [1.2.0] - 2026-01-30
73
+
74
+ ### Added
75
+ - **Series Management**: Robust support for manual ordering and folder-based structures.
76
+ - **Rich Code Blocks**: Syntax highlighting for 11+ languages with copy-to-clipboard.
77
+
78
+ ## [1.1.0] - 2026-01-20
79
+
80
+ ### Added
81
+ - **Testing Suite**: Integrated Vitest/Bun Test with 64+ automated tests.
82
+ - **Integrations**: Support for Giscus comments and multiple analytics providers (Umami/Plausible).
83
+
84
+ ## [1.0.0] - 2026-01-12
85
+
86
+ ### Added
87
+ - **Initial Release**: Launch of **Amytis**, a high-performance digital garden and blog engine.
88
+ - **Next.js Foundation**: Built on App Router for optimal static site generation (SSG).
89
+ - **Advanced Markdown**: Native support for GFM, Mermaid diagrams, and LaTeX math.
90
+ - **Refined Typography**: High-contrast typefaces and optimized readability.
91
+ - **Theming System**: Four built-in palettes (`default`, `blue`, `rose`, `amber`) with Dark Mode.
92
+ - **Content Organization**: Flexible flat-file and nested-folder post structures.
93
+ - **Smart Discovery**: Client-side search, tag clouds, and chronological archives.
94
+ - **SEO & Performance**: Automated Sitemap/RSS generation and optimized WebP delivery.
package/CLAUDE.md CHANGED
@@ -22,7 +22,7 @@ bun test path/to/file.test.ts # Run a single test file
22
22
 
23
23
  # Build
24
24
  bun run build # Full production build (copies assets, builds Next.js, optimizes images)
25
- bun run build:dev # Development build (no image optimization, faster)
25
+ bun run build:dev # Development build (no image optimization, faster) — also regenerates Pagefind search index in public/pagefind/
26
26
  bun run clean # Remove .next, out, public/posts directories
27
27
 
28
28
  # Content creation
@@ -58,6 +58,7 @@ bun run new-flow --mdx # Use .mdx format instead
58
58
 
59
59
  - `site.config.ts` - Site configuration (nav, social, pagination, themes, i18n, analytics, comments)
60
60
  - `src/lib/markdown.ts` - Data access layer with all content query functions
61
+ - `src/lib/search-utils.ts` - Pure search utilities (URL type detection, date extraction, title cleaning, markdown stripping) shared by `Search` and the search index route
61
62
  - `src/app/globals.css` - Theme CSS variables and color palettes
62
63
  - `src/components/MarkdownRenderer.tsx` - MDX rendering with all plugins
63
64
  - `src/i18n/translations.ts` - Language strings for i18n
@@ -187,7 +188,7 @@ chapters:
187
188
  - `SeriesCatalog` - Timeline-style series post listing with numbered entries and progress indicator
188
189
  - `SeriesSidebar` - Series navigation sidebar with progress bar and color-coded states
189
190
  - `SeriesList` - Mobile-optimized series navigation matching sidebar design
190
- - `Search` - Client-side fuzzy search (Cmd/Ctrl+K) using Fuse.js
191
+ - `Search` - Full-text search (Cmd/Ctrl+K) powered by Pagefind (build-time index); features type filter tabs (All/Post/Flow/Book), recent searches, keyboard navigation (arrows + number keys), debounced input, body scroll lock, focus trap, ARIA accessibility, and search syntax tips (`"phrase"`, `-exclude`)
191
192
  - `TableOfContents` - Sticky TOC with scroll tracking, reading progress, and back-to-top
192
193
  - `MarkdownRenderer` - MDX rendering with GFM, math, syntax highlighting, diagrams
193
194
  - `CoverImage` - Optimized image component with WebP support
package/GEMINI.md CHANGED
@@ -1,14 +1,16 @@
1
1
  # Amytis Project Context
2
2
 
3
3
  ## Project Overview
4
- **Amytis** is a high-performance, elegant digital garden and blog engine built with **Next.js 16 (App Router)**, **React 19**, and **Tailwind CSS v4**. It is designed for cultivating thoughts and sharing knowledge with a focus on typography, readability, and flexible content organization.
4
+ **Amytis** (@hutusi/amytis) is a high-performance, elegant digital garden and blog engine built with **Next.js 16 (App Router)**, **React 19**, and **Tailwind CSS v4**. It is designed for cultivating thoughts and sharing knowledge with a focus on typography, readability, and flexible content organization.
5
+
6
+ The package is officially published to both **npm** and **GitHub Packages** with automated **Trusted Publishing** (OIDC).
5
7
 
6
8
  ### Main Technologies
7
9
  - **Framework**: Next.js 16 (App Router)
8
10
  - **Runtime/Package Manager**: [Bun](https://bun.sh/)
9
11
  - **Styling**: Tailwind CSS v4 with CSS-variable based themes and `@tailwindcss/typography`.
10
12
  - **Content**: Local MDX/Markdown files with Zod-validated frontmatter.
11
- - **Search**: Client-side fuzzy search using `Fuse.js`.
13
+ - **Search**: Static full-text search using `Pagefind`.
12
14
  - **Diagrams**: Native support for `Mermaid` diagrams.
13
15
  - **Math**: LaTeX support via `rehype-katex`.
14
16
 
@@ -23,7 +25,7 @@ bun dev
23
25
  ```bash
24
26
  bun run build
25
27
  ```
26
- Generates a fully optimized static site in the `out/` directory.
28
+ Generates a fully optimized static site in the `out/` directory with Pagefind search index.
27
29
 
28
30
  ### Linting & Testing
29
31
  ```bash
@@ -37,10 +39,10 @@ bun test
37
39
  - `posts/`: Paginated post listing and individual post routes.
38
40
  - `flows/`: Stream-style daily notes or micro-blogging (`[year]/[month]/[day]`).
39
41
  - `series/`: Series overview and individual series catalog pages with pagination support.
42
+ - `books/`: Books overview and individual book/chapter pages (`[slug]/[chapter]`).
40
43
  - `archive/`: Timeline-based chronological archive grouped by year and month.
41
44
  - `tags/`: Popularity-sorted tag cloud and filtered listings.
42
45
  - `authors/`: Posts filtered by individual authors.
43
- - `search.json/`: Static search index generator.
44
46
  - `src/lib/`: Core logic and utilities.
45
47
  - `markdown.ts`: Advanced parsing for posts/series/flows, sorting, reading time calculation (multilingual), and metadata inheritance.
46
48
  - `src/components/`: Modular UI blocks (Hero, HorizontalScroll, Search, CoverImage, etc.).
@@ -70,6 +72,7 @@ bun test
70
72
  ### Build Pipeline
71
73
  - **Asset Mapping**: `scripts/copy-assets.ts` mirrors content assets to the public folder, handling relative path resolution for both flat and nested structures.
72
74
  - **Image Optimization**: Fully integrated with `next-image-export-optimizer` for optimized WebP delivery in static exports.
75
+ - **Search Indexing**: `Pagefind` runs after build to generate a static search index from the output directory.
73
76
 
74
77
  ## Recent Updates
75
78
  - Added **Flows** feature: a stream for daily notes and micro-blogging.
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
  ## Features
10
10
 
11
11
  - **Digital Garden Philosophy:** Non-linear navigation through tags, series, authors, books, flows, and chronological archives.
12
- - **Fuzzy Search:** Instant, client-side search across all posts (Cmd/Ctrl+K) powered by Fuse.js.
12
+ - **Full-text Search:** Fast, static client-side search across all content (Cmd/Ctrl+K) powered by Pagefind.
13
13
  - **Structured Content:**
14
14
  - **Series:** Multi-part content organization with manual or automatic ordering.
15
15
  - **Books:** Long-form content with explicit chapters, parts, and a dedicated reading interface.
package/TODO.md CHANGED
@@ -1,76 +1,25 @@
1
- # Future Roadmap
2
-
3
- ## 🚀 High Priority (Next Steps)
4
-
5
- - [ ] **User Experience (UX)**
6
- - [ ] **Code Blocks**: Add a "Copy to Clipboard" button.
7
- - [ ] **Images**: Implement a Lightbox or Zoom-on-click feature.
8
- - [ ] **Navigation**: Add Breadcrumbs (e.g., `Home > Category > Post`).
9
- - [ ] **Navigation**: Add Previous/Next post links at the bottom of articles.
10
-
11
- ## 🌿 Digital Garden Features
12
-
13
- - [ ] **Knowledge Graph**:
14
- - [ ] **Backlinks**: Show "Pages that link here" at the bottom of posts.
15
- - [ ] **Wiki-links**: Support `[[Internal Link]]` syntax.
16
-
17
- ## 🔮 Future Enhancements
18
-
19
- - [ ] **Performance & App**
20
- - [ ] **PWA**: Add `manifest.json` and service workers for offline support.
21
- - [ ] **Search Optimization**: Optimize search index for large gardens (e.g. content segmentation).
22
-
23
- - [ ] **Visuals**
24
- - [ ] **Dynamic OG Images**: Generate custom social cards with post title using `@vercel/og` (Satori).
25
-
26
- - [ ] **CLI Enhancements**
27
- - [ ] **Interactive Mode**: Use prompts to select series, tags, and layouts when creating new posts.
28
-
29
- ## ✅ Completed
30
-
31
- - [x] **Content Types**
32
- - [x] **Flows**: Stream-style daily notes or micro-blogging.
33
- - [x] **Books**: Structured long-form content with chapters.
34
-
35
- - [x] **Engagement**
36
- - [x] **Comments**: Integrate Giscus (GitHub Discussions) for comments.
37
-
38
- - [x] **Engineering**
39
- - [x] **Validation**: Add Zod schema validation for content frontmatter to prevent build errors.
40
- - [x] **Testing**: Add E2E tests for the new search and navigation features.
41
-
42
- - [x] **SEO & Discovery**
43
- - [x] Generate `sitemap.xml` for search engines.
44
- - [x] Generate `rss.xml` / `atom.xml` for feed readers.
45
- - [x] Add Open Graph (OG) meta tags for social sharing.
46
-
47
- - [x] **Navigation & UX**
48
- - [x] Implement a client-side fuzzy Search bar (Command+K).
49
- - [x] Add a sticky Table of Contents (TOC) with Unicode/Multilingual support.
50
- - [x] Add "Reading Time" estimate to post headers.
51
- - [x] Refine link styling (clean default, underline on hover).
52
- - [x] **Hero Section**: Configurable, collapsible welcome mat.
53
- - [x] **Themes**: Configurable color palettes (default, blue, rose, amber).
54
- - [x] **i18n**: Client-side language switcher infrastructure.
55
-
56
- - [x] **Content & Architecture**
57
- - [x] **Series**: Robust support for grouping related posts (file-based & folder-based).
58
- - [x] **Series**: Manual sorting, cross-referencing, and configurable order.
59
- - [x] **Related Posts**: Auto-suggest relevant articles.
60
- - [x] **Cover Images**: Support local paths, external URLs, and generated text covers.
61
- - [x] **Analytics**: Privacy-friendly configuration (Umami/Plausible/Google).
62
-
63
- - [x] **Performance**
64
- - [x] Static Image Optimization (`next-image-export-optimizer`).
65
- - [x] Automated image dimension injection.
66
-
67
- - [x] **CLI Tools**
68
- - [x] `bun run new` script for scaffolding posts.
69
- - [x] `bun run new-series` script for scaffolding series.
70
-
71
- - [x] **UI Polish & Refinements**
72
- - [x] **Animations**: Define missing animation classes.
73
- - [x] **Color Contrast**: Improve accessibility.
74
- - [x] **Responsive Grids**: Improve mobile/tablet layouts.
75
- - [x] **Archive Timeline**: Refine CSS.
76
- - [x] **Loading States**: Add skeleton loaders.
1
+ # Amytis Roadmap
2
+
3
+ ## 🚀 Immediate UX & Polish
4
+ - [ ] **Interactive Code**: Add "Copy to Clipboard" buttons to code blocks.
5
+ - [ ] **Image Zoom**: Implement medium-zoom or a lightbox for MDX images.
6
+ - [ ] **Breadcrumbs**: Add path navigation (e.g., `Home > Books > Chapter`) to all pages.
7
+ - [ ] **Smart Nav**: Add "Previous" and "Next" article links at the bottom of posts.
8
+
9
+ ## 🌿 Digital Garden Evolution
10
+ - [ ] **Backlinks**: Automatically list "Pages that link here" at the bottom of articles.
11
+ - [ ] **Wiki-links**: Support `[[internal-link]]` syntax for easier cross-referencing.
12
+ - [ ] **Recent Notes**: Integrate a "Recent Flows" section on the homepage.
13
+
14
+ ## 🛠 Performance & Social
15
+ - [ ] **Dynamic OG**: Generate automated social cards with Satori based on post titles.
16
+ - [ ] **PWA**: Add a manifest and service worker for basic offline reading support.
17
+ - [ ] **Search UI**: Refine Pagefind results with highlighted context and better mobile layout.
18
+
19
+ ## Completed Highlights
20
+ - [x] **Full-text Search**: Migrated to **Pagefind** for high-performance static indexing.
21
+ - [x] **Multi-format Content**: Native support for **Posts**, **Series**, **Books**, and **Flows**.
22
+ - [x] **Scoped Publishing**: Official release as `@hutusi/amytis` on npm and GitHub.
23
+ - [x] **Robust Engineering**: Zero hydration mismatches, full Zod validation, and 64+ automated tests.
24
+ - [x] **Refined UI**: High-contrast typography, four color palettes, and horizontal featured scrolling.
25
+ - [x] **Asset Pipeline**: Automatic co-located image mapping and WebP optimization.
package/bun.lock CHANGED
@@ -7,7 +7,6 @@
7
7
  "dependencies": {
8
8
  "@giscus/react": "^3.1.0",
9
9
  "@tailwindcss/typography": "^0.5.19",
10
- "fuse.js": "^7.1.0",
11
10
  "github-slugger": "^2.0.0",
12
11
  "gray-matter": "^4.0.3",
13
12
  "image-size": "^2.0.2",
@@ -38,6 +37,7 @@
38
37
  "babel-plugin-react-compiler": "1.0.0",
39
38
  "eslint": "^9.0.0",
40
39
  "eslint-config-next": "16.1.6",
40
+ "pagefind": "^1.4.0",
41
41
  "pdf-to-img": "^5.0.0",
42
42
  "tailwindcss": "^4.1.18",
43
43
  "typescript": "^5.9.3",
@@ -257,6 +257,18 @@
257
257
 
258
258
  "@nolyfill/is-core-module": ["@nolyfill/is-core-module@1.0.39", "", {}, "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA=="],
259
259
 
260
+ "@pagefind/darwin-arm64": ["@pagefind/darwin-arm64@1.4.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-2vMqkbv3lbx1Awea90gTaBsvpzgRs7MuSgKDxW0m9oV1GPZCZbZBJg/qL83GIUEN2BFlY46dtUZi54pwH+/pTQ=="],
261
+
262
+ "@pagefind/darwin-x64": ["@pagefind/darwin-x64@1.4.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-e7JPIS6L9/cJfow+/IAqknsGqEPjJnVXGjpGm25bnq+NPdoD3c/7fAwr1OXkG4Ocjx6ZGSCijXEV4ryMcH2E3A=="],
263
+
264
+ "@pagefind/freebsd-x64": ["@pagefind/freebsd-x64@1.4.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-WcJVypXSZ+9HpiqZjFXMUobfFfZZ6NzIYtkhQ9eOhZrQpeY5uQFqNWLCk7w9RkMUwBv1HAMDW3YJQl/8OqsV0Q=="],
265
+
266
+ "@pagefind/linux-arm64": ["@pagefind/linux-arm64@1.4.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-PIt8dkqt4W06KGmQjONw7EZbhDF+uXI7i0XtRLN1vjCUxM9vGPdtJc2mUyVPevjomrGz5M86M8bqTr6cgDp1Uw=="],
267
+
268
+ "@pagefind/linux-x64": ["@pagefind/linux-x64@1.4.0", "", { "os": "linux", "cpu": "x64" }, "sha512-z4oddcWwQ0UHrTHR8psLnVlz6USGJ/eOlDPTDYZ4cI8TK8PgwRUPQZp9D2iJPNIPcS6Qx/E4TebjuGJOyK8Mmg=="],
269
+
270
+ "@pagefind/windows-x64": ["@pagefind/windows-x64@1.4.0", "", { "os": "win32", "cpu": "x64" }, "sha512-NkT+YAdgS2FPCn8mIA9bQhiBs+xmniMGq1LFPDhcFn0+2yIUEiIG06t7bsZlhdjknEQRTSdT7YitP6fC5qwP0g=="],
271
+
260
272
  "@rtsao/scc": ["@rtsao/scc@1.1.0", "", {}, "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g=="],
261
273
 
262
274
  "@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
@@ -767,8 +779,6 @@
767
779
 
768
780
  "functions-have-names": ["functions-have-names@1.2.3", "", {}, "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ=="],
769
781
 
770
- "fuse.js": ["fuse.js@7.1.0", "", {}, "sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ=="],
771
-
772
782
  "generator-function": ["generator-function@2.0.1", "", {}, "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g=="],
773
783
 
774
784
  "gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
@@ -1173,6 +1183,8 @@
1173
1183
 
1174
1184
  "package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="],
1175
1185
 
1186
+ "pagefind": ["pagefind@1.4.0", "", { "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" }, "bin": { "pagefind": "lib/runner/bin.cjs" } }, "sha512-z2kY1mQlL4J8q5EIsQkLzQjilovKzfNVhX8De6oyE6uHpfFtyBaqUpcl/XzJC/4fjD8vBDyh1zolimIcVrCn9g=="],
1187
+
1176
1188
  "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
1177
1189
 
1178
1190
  "parse-entities": ["parse-entities@4.0.2", "", { "dependencies": { "@types/unist": "^2.0.0", "character-entities-legacy": "^3.0.0", "character-reference-invalid": "^2.0.0", "decode-named-character-reference": "^1.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0", "is-hexadecimal": "^2.0.0" } }, "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw=="],
@@ -75,7 +75,7 @@ src/app/
75
75
 
76
76
  ### Navigation & Discovery
77
77
  - **`TableOfContents`** - Sticky TOC with scroll-based tracking.
78
- - **`Search`** - Client-side fuzzy search modal (Cmd/Ctrl+K).
78
+ - **`Search`** - Full-text search modal (Cmd/Ctrl+K) powered by Pagefind. Supports type filter tabs (All/Post/Flow/Book), recent searches, keyboard navigation, debounced input, focus trap, and ARIA accessibility. Search syntax: `"exact phrase"`, `word1 word2` (AND), `-exclude`.
79
79
  - **`Pagination`** - Previous/Next page navigation.
80
80
  - **`ReadingProgressBar`** - Top-of-page progress bar for book chapters.
81
81
 
@@ -100,4 +100,5 @@ Theming is handled by `next-themes` and Tailwind CSS v4. `src/app/globals.css` d
100
100
 
101
101
  1. **`scripts/copy-assets.ts`** - Copies images from content directories (`posts/`, `series/`, `books/`, `flows/`) to `public/posts/` for static hosting.
102
102
  2. **`next build`** - Next.js static export to `out/`.
103
- 3. **`next-image-export-optimizer`** - Generates optimized WebP variants.
103
+ 3. **`next-image-export-optimizer`** - Generates optimized WebP variants (production build only).
104
+ 4. **`pagefind --site out`** - Crawls the exported HTML and builds a full-text search index in `out/pagefind/`. The index is loaded at runtime by `src/components/Search.tsx` via a dynamic import. Pure utility functions used by the search component and the search index route live in `src/lib/search-utils.ts`.
@@ -13,6 +13,8 @@
13
13
  ```
14
14
  Open [http://localhost:3000](http://localhost:3000).
15
15
 
16
+ > **Search in dev:** The search index is generated by `pagefind` at build time. Run `bun run build:dev` once to generate `public/pagefind/`. After that, the search modal (Cmd/Ctrl+K) will work while `bun dev` is running. Re-run `bun run build:dev` whenever content changes.
17
+
16
18
  ## Writing Content
17
19
 
18
20
  ### Creating Posts
@@ -74,8 +76,8 @@ bun run test:e2e # Run end-to-end tests
74
76
  ## Building
75
77
 
76
78
  ```bash
77
- bun run build # Production build
78
- bun run build:dev # Development build (faster)
79
+ bun run build # Production build (includes image optimization and Pagefind index)
80
+ bun run build:dev # Development build (faster, no image optimization; also generates Pagefind index)
79
81
  ```
80
82
 
81
83
  ## Code Style
@@ -17,7 +17,7 @@ bun run build:dev
17
17
  bun run clean && bun run build
18
18
  ```
19
19
 
20
- The `out/` directory contains plain HTML, CSS, JS, and images — ready to be served by any static file server.
20
+ The `out/` directory contains plain HTML, CSS, JS, images, and the Pagefind search index (`out/pagefind/`) — ready to be served by any static file server.
21
21
 
22
22
  ### Preview Locally
23
23
 
@@ -190,6 +190,11 @@ server {
190
190
  add_header Cache-Control "public";
191
191
  }
192
192
 
193
+ # Cache Pagefind search index (regenerated on each build, so short TTL is fine)
194
+ location /pagefind/ {
195
+ add_header Cache-Control "public, max-age=3600";
196
+ }
197
+
193
198
  # trailingSlash is true, so pages are slug/index.html
194
199
  # Redirect URLs without trailing slash to add one (except files)
195
200
  location / {
@@ -228,6 +233,9 @@ yourdomain.com {
228
233
  @postassets path /posts/*
229
234
  header @postassets Cache-Control "public, max-age=2592000"
230
235
 
236
+ @pagefind path /pagefind/*
237
+ header @pagefind Cache-Control "public, max-age=3600"
238
+
231
239
  handle_errors {
232
240
  rewrite * /404/index.html
233
241
  file_server
package/eslint.config.mjs CHANGED
@@ -12,6 +12,8 @@ const eslintConfig = defineConfig([
12
12
  "out/**",
13
13
  "build/**",
14
14
  "next-env.d.ts",
15
+ // Generated at build time — not authored code
16
+ "public/pagefind/**",
15
17
  ]),
16
18
  ]);
17
19
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hutusi/amytis",
3
- "version": "1.5.6",
3
+ "version": "1.6.0",
4
4
  "description": "A high-performance digital garden and blog engine with Next.js 16 and Tailwind CSS v4",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,8 +14,8 @@
14
14
  "packageManager": "bun@1.3.4",
15
15
  "scripts": {
16
16
  "dev": "next dev",
17
- "build": "bun scripts/copy-assets.ts && next build && next-image-export-optimizer",
18
- "build:dev": "bun scripts/copy-assets.ts && next build",
17
+ "build": "bun scripts/copy-assets.ts && next build && next-image-export-optimizer && pagefind --site out",
18
+ "build:dev": "bun scripts/copy-assets.ts && next build && pagefind --site out --output-path public/pagefind",
19
19
  "validate": "bun run lint && bun run test && bun run build:dev",
20
20
  "clean": "rm -rf .next out public/posts public/books public/flows",
21
21
  "new": "bun scripts/new-post.ts",
@@ -35,7 +35,6 @@
35
35
  "dependencies": {
36
36
  "@giscus/react": "^3.1.0",
37
37
  "@tailwindcss/typography": "^0.5.19",
38
- "fuse.js": "^7.1.0",
39
38
  "github-slugger": "^2.0.0",
40
39
  "gray-matter": "^4.0.3",
41
40
  "image-size": "^2.0.2",
@@ -66,6 +65,7 @@
66
65
  "babel-plugin-react-compiler": "1.0.0",
67
66
  "eslint": "^9.0.0",
68
67
  "eslint-config-next": "16.1.6",
68
+ "pagefind": "^1.4.0",
69
69
  "pdf-to-img": "^5.0.0",
70
70
  "tailwindcss": "^4.1.18",
71
71
  "typescript": "^5.9.3"
@@ -1,7 +1,4 @@
1
1
  {
2
2
  "posts/02-routing-mastery/assets/m-p-model.png": "fDmvlEkZnE-UCvPK4gmDkJD7SU8coOTl4iw5hpsmcWI=",
3
- "posts/advanced-markdown/images/m-p-model.png": "BdYG3Wq+FcOnoSrZeJeb6x2V-LsB-gwvms3WQJFq+Wg=",
4
- "posts/part-1/images/m-p-model.png": "94OaqjvkCmDcz+Iuhw14vHXYUzYl3Y8+wwoU1CQZ6l0=",
5
- "posts/part-2-rich-content/images/m-p-model.png": "Vp5bOs9N2OHHjMM2PFntkkCl1uY7DleLymwrSHbecOA=",
6
3
  "/screenshot.png": "dGCNrjp1oMIL3NrVh1VDW0K+7Pp-cI5KH6tW4-6o9zg="
7
4
  }
@@ -62,7 +62,7 @@ export default async function FlowPage({ params }: { params: Promise<{ year: str
62
62
  <article className="flex-1 min-w-0">
63
63
  {/* Header */}
64
64
  <header className="mb-8">
65
- <time className="text-sm font-mono text-accent">{flow.date}</time>
65
+ <time className="text-sm font-mono text-accent" data-pagefind-meta="date[content]">{flow.date}</time>
66
66
  <h1 className="mt-2 text-3xl md:text-4xl font-serif font-bold text-heading">{flow.title}</h1>
67
67
  </header>
68
68
 
@@ -88,6 +88,7 @@ export default function RootLayout({
88
88
  <body
89
89
  className={`${inter.variable} ${baskerville.variable} font-sans min-h-screen transition-colors duration-300`}
90
90
  data-palette={siteConfig.themeColor}
91
+ suppressHydrationWarning
91
92
  >
92
93
  {/* Skip to main content link for accessibility */}
93
94
  <a
@@ -1,4 +1,5 @@
1
1
  import { getAllPosts, getAllBooks, getBookChapter, getAllFlows } from '@/lib/markdown';
2
+ import { stripMarkdown } from '@/lib/search-utils';
2
3
 
3
4
  export const dynamic = 'force-static';
4
5
 
@@ -12,6 +13,7 @@ export async function GET() {
12
13
  excerpt: post.excerpt,
13
14
  category: post.category,
14
15
  tags: post.tags,
16
+ content: stripMarkdown(post.content),
15
17
  }));
16
18
 
17
19
  // Add book chapters to search index
@@ -27,6 +29,7 @@ export async function GET() {
27
29
  excerpt: chapter.excerpt || '',
28
30
  category: 'Book',
29
31
  tags: [],
32
+ content: stripMarkdown(chapter.content),
30
33
  });
31
34
  }
32
35
  }
@@ -42,6 +45,7 @@ export async function GET() {
42
45
  excerpt: flow.excerpt,
43
46
  category: 'Flow',
44
47
  tags: flow.tags,
48
+ content: stripMarkdown(flow.content),
45
49
  });
46
50
  }
47
51