-
Notifications
You must be signed in to change notification settings - Fork 142
Add PageFind beta (Full Text Search across Site) #2771
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request adds Pagefind as a beta search feature to MarkBind, providing static full-text search capabilities without requiring external services. The implementation integrates Pagefind indexing into the build process and automatically injects the necessary UI scripts and styles when enableSearch is enabled.
Changes:
- Added pagefind npm package (v1.4.0) as a dependency
- Integrated pagefind indexing in the site generation process after all assets are copied
- Updated page templates to conditionally inject pagefind CSS and JavaScript resources
Reviewed changes
Copilot reviewed 118 out of 120 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/core/src/Site/index.ts | Added indexSiteWithPagefind() method and integrated it into the build process |
| packages/core/src/Page/pagefindScript.ts | New file containing the pagefind UI initialization script |
| packages/core/src/Page/page.njk | Updated template to inject pagefind CSS/JS when enabled |
| packages/core/src/Page/PageConfig.ts | Added pagefind-related properties to PageAssets interface |
| packages/core/package.json | Added pagefind v1.4.0 dependency |
| packages/cli/test/functional/testUtil/compare.js | Updated comparison utility to ignore pagefind directories |
| packages/cli/test/functional/test.js | Updated tests to ignore generated pagefind directories |
| .gitignore / .eslintignore | Added patterns to ignore pagefind-generated files |
| docs/userGuide/makingTheSiteSearchable.md | Added documentation for the new pagefind beta feature |
| packages/cli/test/functional//expected//*.html | Updated expected test outputs to include pagefind scripts |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const { index } = await createIndex({ | ||
| keepIndexUrl: true, | ||
| verbose: true, | ||
| logfile: 'debug.log', | ||
| }); |
Copilot
AI
Jan 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The verbose and logfile options should not be hardcoded in production code. The verbose: true and logfile: 'debug.log' configuration will create debug log files and produce excessive console output for all users. Consider either removing these options or making them conditional based on an environment variable or debug flag.
| } else { | ||
| logger.error('Pagefind failed to create index'); | ||
| } | ||
| await close(); |
Copilot
AI
Jan 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing error handling for the close() call. If the close operation fails, the error should be caught and logged to prevent unhandled promise rejections.
| new window.PagefindUI({ | ||
| element: container, | ||
| showSubResults: true, | ||
| showImages: false, | ||
| }); | ||
| }); |
Copilot
AI
Jan 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing error handling for the PagefindUI instantiation. If the window.PagefindUI constructor is not available (e.g., if the script fails to load), this will throw an uncaught error. Consider checking for the existence of window.PagefindUI before attempting to instantiate it.
|
|
||
| ## Using External Search Services | ||
|
|
||
| MarkBind sites can use Algolia Doc Search services easily via the Algolia plugin. Unlike the built-in search, Algolia provides full-text search. See the panel below for more info. |
Copilot
AI
Jan 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation states that Pagefind provides "full-text search capabilities without external services" (line 44), but then on line 71, it says "Unlike the built-in search, Algolia provides full-text search." This creates confusion about whether the built-in Pagefind feature provides full-text search or not. The messaging should be clarified for consistency.
| MarkBind sites can use Algolia Doc Search services easily via the Algolia plugin. Unlike the built-in search, Algolia provides full-text search. See the panel below for more info. | |
| MarkBind sites can use Algolia Doc Search services easily via the Algolia plugin. Algolia is a hosted service that also provides full-text search and advanced search features. See the panel below for more info. |
| if (this.siteConfig.enableSearch) { | ||
| await this.indexSiteWithPagefind(); | ||
| } |
Copilot
AI
Jan 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pagefind indexing should be wrapped in a try-catch block or the error should be propagated properly. Currently, if indexSiteWithPagefind() throws an error, it will bypass the error handler at line 556-558 and potentially leave the build in an inconsistent state. Consider wrapping the pagefind call in try-catch to log the error and continue the build, or ensure errors are properly propagated.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #2771 +/- ##
==========================================
- Coverage 62.30% 62.13% -0.17%
==========================================
Files 130 131 +1
Lines 7184 7213 +29
Branches 1580 1521 -59
==========================================
+ Hits 4476 4482 +6
+ Misses 2644 2535 -109
- Partials 64 196 +132 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
A sample for CS2103 website is here: https://changerteck.com/website-2526S1/admin/usingThisWebsite.html
|
This is great. Thanks for the quick turnaround, @gerteck Next step could be to block certain paths from search results. For example, searching for 'refactoring' gives the following top three results. It's nice if we can block the first and the third and just limit to the 2nd one. https://changerteck.com/website-2526S1/book/refactoring/index.html Not sure if this kind of blocking can be implemented in the current stop-gap implementation or we need for the 'proper' implementation later. In the meantime, I'll test it a bit more to see if it is already good enough to go into the live site. |
Thinking about it, I think we can come up with a search blocking that conforms to the current interface already used (i.e. searchable: "no"), without too much issue or compromising the code maintainability. |
Yup. It is already in the site.json (in the |
|
@gerteck On a related note, we currently tell Algolia to omit an element from indexing using a class |
PageFind works similarly, which makes use of https://pagefind.app/docs/indexing/#removing-individual-elements-from-the-index |


What is the purpose of this pull request?
Overview of changes:
#2568
Instead of chasing perfection, let's release a simple integration version of pagefind first.
Original Search Issue is #205
Didn't add any testcases as this is just a beta feature.
Anything you'd like to highlight/discuss:
Testing instructions:
Proposed commit message: (wrap lines at 72 characters)
Add basic PageFind Functionality with default UI
Checklist: ☑️
Reviewer checklist:
Indicate the SEMVER impact of the PR:
At the end of the review, please label the PR with the appropriate label:
r.Major,r.Minor,r.Patch.Breaking change release note preparation (if applicable):