Skip to content

Add PageFind beta V2 (Full Text Search across Site) - #2857

Merged
MoshiMoshiMochi merged 42 commits into
MarkBind:masterfrom
MoshiMoshiMochi:feat/pagefind-beta
Mar 25, 2026
Merged

Add PageFind beta V2 (Full Text Search across Site)#2857
MoshiMoshiMochi merged 42 commits into
MarkBind:masterfrom
MoshiMoshiMochi:feat/pagefind-beta

Conversation

@MoshiMoshiMochi

@MoshiMoshiMochiMoshiMoshiMochi commented Mar 11, 2026

Copy link
Copy Markdown
Contributor

What is the purpose of this pull request?

  • Documentation update
  • Bug fix
  • Feature addition or enhancement
  • Code maintenance
  • DevOps
  • Improve developer experience
  • Others, please explain:

Overview of changes:

Initial version of pagefind (based on #2771)

Original Search Issue is #205

No test cases yet.

Anything you'd like to highlight/discuss:

  1. Created a new Search.vue component <search /> that renders the pagefind search modal.
    • The CSS of which definitely isn't a finish product.
    • Additionally we could consider updating how we present the data.
Heres how the modal currently looks vs Algolia's (CS2103 site)

Current implementation of pagefind.
image

Algolia's styling on CS2103 website
image

From the 2 images above, I believe that Algolia's styling is notably more structured in how it represents the search results and subresults, notably on how they group the search results.

The blog we used as reference for the styling formats the pagefindresults by processing the search results. More information on how to access the specific search results information can be found here.

  1. Added pagefind configuration options within site.json to enable more flexible filtering options. Users can declare
    • exclude_selectors option to exclude specific elements from being searchable.
    • glob option to limit which pages are indexed by Pagefind.
{
"pagefind": {
"exclude_selectors": [".algolia-no-index", "[class*='algolia-no-index']"]
"glob": ["**/devGuide/**", "**/userGuide/**"]
}
}
  • from the example above,
    • exclude_selectors: tells Pagefind to exclude any element with the algolia-no-index class from the searchable results. It works the same way as declaring data-pagefind-ignore.
    • glob: Pagefind will only index pages that are found inside devGuide and userGuide directories (including subdirectories).

All in all, theres still a lot more things we can do to improve this pagefind feature (like page weighting, ranking, sortingetc). But this is all I've managed to conjure up thus far.

Let me know what yall think of these updates to the pagefind feature (there might be better ways to filter pages, this is just from my interpretation when reading through the pagefind docs). Let me know if I missed out on anything in particular or should be focusing my efforts more towards.

  • Definitely going to spend more time working on the styling. But I think if we're gonna process and present our data differently from the base Pagefind UI, then we should probably work on those at the same time since they are intrinsically linked.
  • Also needa write testcases 😔. Not looking forward to that 😢

Testing instructions:

Proposed commit message: (wrap lines at 72 characters)

Add base Pagefind with updated UI & extra filtering functionalities


Checklist: ☑️

  • Updated the documentation for feature additions and enhancements
  • Added tests for bug fixes or features
  • Linked all related issues
  • No unrelated changes

Reviewer checklist:

Indicate the SEMVER impact of the PR:

  • Major (when you make incompatible API changes)
  • Minor (when you add functionality in a backward compatible manner)
  • Patch (when you make backward compatible bug fixes)

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):

  • To be included in the release note for any feature that is made obsolete/breaking

Give a brief explanation note about:

  • what was the old feature that was made obsolete
  • any replacement feature (if any), and
  • how the author should modify his website to migrate from the old feature to the replacement feature (if possible).

This added support for configuring Pagefind search indexing via
site.json is aimed towards allowing users to declare glob patterns to
customize what pages in which directory should be indexed by pagefind.
Initially, I felt that including the root_selector option and
force_language option would be useful for pagefind configuration
options. But perhaps for now it isn't the most pressing issue so I'm
going to exlcude it from the current implementation of pagefind.
This helps resolve an issue with generate() test case within
Site.functional.test.ts. Namely, because Jest's cannot intercept
eval('import("pagefind")') runtime dynamic import used by pagefind.
Hence, for now at least, the error handling would catch this error and
allow the site generation to continue normally.
Extracted processResult into its own helper function.
Added rel="noopener noreferrer" attribute for improved security and
privacy when being redirected to pagefind's github repo.
@codecov

codecovBot commented Mar 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.18321% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.88%. Comparing base (64c1dca) to head (0b71c41).
⚠️ Report is 1 commits behind head on master.

Files with missing linesPatch %Lines
packages/core/src/Site/SiteGenerationManager.ts96.00%3 Missing ⚠️
packages/core/test/unit/utils/data.ts83.33%2 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #2857 +/- ##
==========================================
+ Coverage 70.41% 70.88% +0.47% 
==========================================
Files 129 131 +2 Lines 6952 7083 +131 Branches 1578 1660 +82 ==========================================
+ Hits 4895 5021 +126 - Misses 1957 1962 +5 
Partials 100 100 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@MoshiMoshiMochi

MoshiMoshiMochi commented Mar 19, 2026

Copy link
Copy Markdown
ContributorAuthor

Hi guys, sorry for the wait, marking this as ready to review!

As mentioned in the PR description, while I believe there are still plenty of things that we can work on to enhancing the Pagefind feature in the future.

Namely, we could take a look at

  1. Creating a subsection for our results (similar to how algolia does it, as discussed in last week's meeting). I kinda have an idea of how to extract and process the results information so definitely will work on this as soon as this PR is merged.

  2. Get it to work on hot reloading

We can probably make separate issues for these things.

The current implementation is far from perfect (e.g. a lot of css can be improved, clearly still an issue when using at different browser sizes, also a lot of z level issues with the navbar & nav components).

So let me know of what yall think of the current implementation, anything to improve, anything pressing to fix, etc.

@MarkBind/active-3281-members

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Pagefind-based full-text search to MarkBind as a beta feature, including build-time indexing, asset injection into generated pages, a new Vue <search /> modal UI, and supporting configuration/docs/test updates.

Changes:

  • Introduce a new Vue Search component (Pagefind UI modal) and styling assets.
  • Generate and inject Pagefind search assets during site generation, with site.json support for pagefind.exclude_selectors and pagefind.glob.
  • Update unit/functional tests, expected HTML outputs, and tooling ignores to accommodate generated Pagefind artifacts.

Reviewed changes

Copilot reviewed 128 out of 130 changed files in this pull request and generated 10 comments.

Show a summary per file
FileDescription
packages/vue-components/src/pagefindSearchBar/assets/search.cssAdds global CSS for the Pagefind search modal styling.
packages/vue-components/src/pagefindSearchBar/Search.vueNew Pagefind-backed search modal component + keyboard handling and UI overrides.
packages/vue-components/src/pagefindSearchBar/LogoPagefind.vueAdds Pagefind logo SVG for the modal footer.
packages/vue-components/src/index.jsRegisters the new Search component for <search /> usage.
packages/vue-components/src/tests/Search.spec.jsAdds unit tests for the new Search component behavior.
packages/core/test/unit/utils/data.tsAdds factories/helpers for mocking Pagefind and generating site.json with Pagefind config.
packages/core/test/unit/Site/SiteGenerationManager.test.tsAdds unit tests for Pagefind glob normalization/validation and indexing behavior.
packages/core/src/Site/SitePagesManager.tsInjects Pagefind UI CSS/JS asset paths into page rendering assets when search is enabled.
packages/core/src/Site/SiteGenerationManager.tsAdds Pagefind indexing during site generation and glob filtering support.
packages/core/src/Site/SiteConfig.tsExtends site config to include optional pagefind configuration.
packages/core/src/Page/page.njkInjects Pagefind UI stylesheet/script into generated pages when available.
packages/core/src/Page/PageConfig.tsAdds pagefindCss/pagefindJs to PageAssets type.
packages/core/package.jsonAdds pagefind dependency for build-time indexing.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/UserGuide.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/QuickStart.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/Features.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/FAQ.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/team/johndoe.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/team/AboutUs.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/TracingCode.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Testing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/SettingUp.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Requirements.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Implementation.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Documentation.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/DeveloperGuide.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/DevOps.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Design.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Configuration.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_portfolio/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_minimal/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_table_plugin/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_special_tags/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_3.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/about.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/README.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/Page-1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/Home.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/about.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/_Sidebar.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/_Footer.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/Page-1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/Home.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_algolia_plugin/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/test_md_fragment.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testWeb3FormPlugin.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testVariableContainsInclude.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testTree.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testTooltipSpacing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testThumbnails.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testSourceContainScript.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testSingleAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPopovers.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPopoverTrigger.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPlantUML.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanelsClosingTransition.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanels.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanelMarkdownParsing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavWithoutTitleAndNavHeadings.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavWithOnlyTitle.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavTarget.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavPrint.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNav.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testOcticonInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testModals.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMermaid.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMath.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMaterialIconsInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testList.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLinks.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsWithAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsOverrideWithAltFrontmatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsOverride.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayouts.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludePluginsRendered.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludeMultipleModals.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludeBoilerplate.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testImages.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIconsInSiteLayout.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testHr.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testGlyphiconInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testFontAwesomeInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testExternalScripts.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testEmptyFrontmatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testEmptyAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testDates.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testCodeBlocks.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testCenterText.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testBootstrapIconInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAntiFOUCStyles.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAnnotate.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAnchorGeneration.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAltFrontMatterParsing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAltFrontMatterInvalidKeyValue.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/nested_sub_site/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/nested_sub_site/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/bugs/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/testUtil/compare.tsAdds ignore support for generated Pagefind outputs in functional comparisons.
packages/cli/test/functional/test.tsUses new compare() signature to ignore generated pagefind/ directories.
package-lock.jsonLocks Pagefind and platform-specific optional dependencies.
docs/userGuide/makingTheSiteSearchable.mdDocuments Pagefind beta usage and new site.json options.
.stylelintrc.jsAdds stylelint override for Pagefind UI class naming patterns.
.gitignoreIgnores generated Pagefind directories and fragments.
.eslintrc.jsAdds ESLint ignore patterns for generated/build output directories.
.eslintignoreIgnores generated Pagefind JS under functional test outputs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/core/src/Site/SitePagesManager.ts Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/assets/search.css Outdated
Comment threadpackages/core/src/Site/SiteGenerationManager.ts

@Harjun751Harjun751 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huge effort, and it definitely paid off!

Requesting some changes/clarifications for the

  • debug.log file
  • empty glob parsing
  • windows directory safety check
  • spawned watcher

issues, but other than that it's all minor nits. After the above I think we'll be in a good state.

Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threadpackages/core/src/Page/PageConfig.ts
Comment threadpackages/core/src/Site/SitePagesManager.ts Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts Outdated
Now indexSiteWithPagefind returns a boolean which is then determines if
there is a need to inject the pagefindcss & pagefindJs.
Since isValidGlobPattern is only used by normalizeGlobPattern, changed
it to private access. Now normalization of pattern happens solely in
normalizeGlobPattern and validation is purely a validation method.
Better separation of concerns.
Also resolved a bug where the 404s required pages to be created before
knowing if indexing succeeds by defaulting index success to true and
only if it fails does the flag get set to false.
@gerteck

gerteck commented Mar 22, 2026

Copy link
Copy Markdown
Member

I tried dropping the default pagefind-ui.css and realized the search component is depending on it quite heavily

image

Comment threaddocs/userGuide/makingTheSiteSearchable.md
@gerteck

Copy link
Copy Markdown
Member

Good first step introducing pagefind into MarkBind @MoshiMoshiMochi . The build-time integration (Node API, createIndex/addDirectory/writeFiles, glob support, exclude_selectors config) is solid and the right approach.

The main concern is in Search.vue. The current implementation wraps window.PagefindUI — a pre-built UI component that injects its own DOM, inside a custom modal shell, then works against PagefindUI's behaviour to get the desired result:

  • ~70 lines of :deep(.pagefind-ui__*) CSS overrides to fight PagefindUI's default styles
  • A MutationObserver to detect when PagefindUI renders results (needed because Search.vue has no direct control over PagefindUI's rendering
    lifecycle)
  • Custom keyboard navigation running alongside PagefindUI's own keyboard handling
  • container.innerHTML = '' on modal close as a teardown workaround (PagefindUI has no destroy API)
  • Silent failure if window.PagefindUI is undefined (script load error goes unnoticed)

This is workable for a first cut, but the cause-and-effect is opaque, where future contributors would need to understand both the PagefindUI internals and overrides to make changes safely. It also loads pagefind-ui.js (84.6KB) + pagefind-ui.css (14.5KB) on every page, when we only need pagefind.js (33.8KB).

The long-term direction should be:

  • Replace window.PagefindUI with the lower-level pagefind.js API, which lets you query the index directly and returns plain data objects
  • Ideally, Search.vue owns all the DOM natively as Vue reactive state — no CSS overrides, no MutationObserver, no innerHTML teardown, no global window dependency.

Suggest tracking this as follow-up issues:

  1. Replace window.PagefindUI with pagefind.js lower-level API — remove the <script src="pagefind-ui.js"> global, dynamically import pagefind.js inside the component instead
  2. In-house result rendering — render results natively in the Vue template (title, excerpt, sub-results, active highlight) instead of delegating to PagefindUI's DOM
  3. In-house CSS — replace :deep() overrides with first-party styles scoped to our own markup

I think it is okay to approve as a foundation if these follow-ups are tracked, since the build-time indexing is correct and the search does work end-to-end, just wanted to clarify on your architectural direction for the component moving forward! @MoshiMoshiMochi

@Harjun751Harjun751 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes I requested are addressed 👍

@MoshiMoshiMochi
MoshiMoshiMochi merged commit 19b34fe into MarkBind:masterMar 25, 2026
10 checks passed
@github-actions

Copy link
Copy Markdown

@MoshiMoshiMochi Each PR must have a SEMVER impact label, please remember to label the PR properly.

@gerteckgerteck added the r.Minor Version resolver: increment by 0.1.0 label Mar 26, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

r.MinorVersion resolver: increment by 0.1.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@MoshiMoshiMochi@gerteck@Harjun751
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Add PageFind beta V2 (Full Text Search across Site) by MoshiMoshiMochi · Pull Request #2857 · MarkBind/markbind · GitHub
Skip to content

Add PageFind beta V2 (Full Text Search across Site) - #2857

Merged
MoshiMoshiMochi merged 42 commits into
MarkBind:masterfrom
MoshiMoshiMochi:feat/pagefind-beta
Mar 25, 2026
Merged

Add PageFind beta V2 (Full Text Search across Site)#2857
MoshiMoshiMochi merged 42 commits into
MarkBind:masterfrom
MoshiMoshiMochi:feat/pagefind-beta

Conversation

@MoshiMoshiMochi

@MoshiMoshiMochiMoshiMoshiMochi commented Mar 11, 2026

Copy link
Copy Markdown
Contributor

What is the purpose of this pull request?

  • Documentation update
  • Bug fix
  • Feature addition or enhancement
  • Code maintenance
  • DevOps
  • Improve developer experience
  • Others, please explain:

Overview of changes:

Initial version of pagefind (based on #2771)

Original Search Issue is #205

No test cases yet.

Anything you'd like to highlight/discuss:

  1. Created a new Search.vue component <search /> that renders the pagefind search modal.
    • The CSS of which definitely isn't a finish product.
    • Additionally we could consider updating how we present the data.
Heres how the modal currently looks vs Algolia's (CS2103 site)

Current implementation of pagefind.
image

Algolia's styling on CS2103 website
image

From the 2 images above, I believe that Algolia's styling is notably more structured in how it represents the search results and subresults, notably on how they group the search results.

The blog we used as reference for the styling formats the pagefindresults by processing the search results. More information on how to access the specific search results information can be found here.

  1. Added pagefind configuration options within site.json to enable more flexible filtering options. Users can declare
    • exclude_selectors option to exclude specific elements from being searchable.
    • glob option to limit which pages are indexed by Pagefind.
{
"pagefind": {
"exclude_selectors": [".algolia-no-index", "[class*='algolia-no-index']"]
"glob": ["**/devGuide/**", "**/userGuide/**"]
}
}
  • from the example above,
    • exclude_selectors: tells Pagefind to exclude any element with the algolia-no-index class from the searchable results. It works the same way as declaring data-pagefind-ignore.
    • glob: Pagefind will only index pages that are found inside devGuide and userGuide directories (including subdirectories).

All in all, theres still a lot more things we can do to improve this pagefind feature (like page weighting, ranking, sortingetc). But this is all I've managed to conjure up thus far.

Let me know what yall think of these updates to the pagefind feature (there might be better ways to filter pages, this is just from my interpretation when reading through the pagefind docs). Let me know if I missed out on anything in particular or should be focusing my efforts more towards.

  • Definitely going to spend more time working on the styling. But I think if we're gonna process and present our data differently from the base Pagefind UI, then we should probably work on those at the same time since they are intrinsically linked.
  • Also needa write testcases 😔. Not looking forward to that 😢

Testing instructions:

Proposed commit message: (wrap lines at 72 characters)

Add base Pagefind with updated UI & extra filtering functionalities


Checklist: ☑️

  • Updated the documentation for feature additions and enhancements
  • Added tests for bug fixes or features
  • Linked all related issues
  • No unrelated changes

Reviewer checklist:

Indicate the SEMVER impact of the PR:

  • Major (when you make incompatible API changes)
  • Minor (when you add functionality in a backward compatible manner)
  • Patch (when you make backward compatible bug fixes)

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):

  • To be included in the release note for any feature that is made obsolete/breaking

Give a brief explanation note about:

  • what was the old feature that was made obsolete
  • any replacement feature (if any), and
  • how the author should modify his website to migrate from the old feature to the replacement feature (if possible).

This added support for configuring Pagefind search indexing via
site.json is aimed towards allowing users to declare glob patterns to
customize what pages in which directory should be indexed by pagefind.
Initially, I felt that including the root_selector option and
force_language option would be useful for pagefind configuration
options. But perhaps for now it isn't the most pressing issue so I'm
going to exlcude it from the current implementation of pagefind.
This helps resolve an issue with generate() test case within
Site.functional.test.ts. Namely, because Jest's cannot intercept
eval('import("pagefind")') runtime dynamic import used by pagefind.
Hence, for now at least, the error handling would catch this error and
allow the site generation to continue normally.
Extracted processResult into its own helper function.
Added rel="noopener noreferrer" attribute for improved security and
privacy when being redirected to pagefind's github repo.
@codecov

codecovBot commented Mar 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.18321% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.88%. Comparing base (64c1dca) to head (0b71c41).
⚠️ Report is 1 commits behind head on master.

Files with missing linesPatch %Lines
packages/core/src/Site/SiteGenerationManager.ts96.00%3 Missing ⚠️
packages/core/test/unit/utils/data.ts83.33%2 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #2857 +/- ##
==========================================
+ Coverage 70.41% 70.88% +0.47% 
==========================================
Files 129 131 +2 Lines 6952 7083 +131 Branches 1578 1660 +82 ==========================================
+ Hits 4895 5021 +126 - Misses 1957 1962 +5 
Partials 100 100 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@MoshiMoshiMochi

MoshiMoshiMochi commented Mar 19, 2026

Copy link
Copy Markdown
ContributorAuthor

Hi guys, sorry for the wait, marking this as ready to review!

As mentioned in the PR description, while I believe there are still plenty of things that we can work on to enhancing the Pagefind feature in the future.

Namely, we could take a look at

  1. Creating a subsection for our results (similar to how algolia does it, as discussed in last week's meeting). I kinda have an idea of how to extract and process the results information so definitely will work on this as soon as this PR is merged.

  2. Get it to work on hot reloading

We can probably make separate issues for these things.

The current implementation is far from perfect (e.g. a lot of css can be improved, clearly still an issue when using at different browser sizes, also a lot of z level issues with the navbar & nav components).

So let me know of what yall think of the current implementation, anything to improve, anything pressing to fix, etc.

@MarkBind/active-3281-members

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Pagefind-based full-text search to MarkBind as a beta feature, including build-time indexing, asset injection into generated pages, a new Vue <search /> modal UI, and supporting configuration/docs/test updates.

Changes:

  • Introduce a new Vue Search component (Pagefind UI modal) and styling assets.
  • Generate and inject Pagefind search assets during site generation, with site.json support for pagefind.exclude_selectors and pagefind.glob.
  • Update unit/functional tests, expected HTML outputs, and tooling ignores to accommodate generated Pagefind artifacts.

Reviewed changes

Copilot reviewed 128 out of 130 changed files in this pull request and generated 10 comments.

Show a summary per file
FileDescription
packages/vue-components/src/pagefindSearchBar/assets/search.cssAdds global CSS for the Pagefind search modal styling.
packages/vue-components/src/pagefindSearchBar/Search.vueNew Pagefind-backed search modal component + keyboard handling and UI overrides.
packages/vue-components/src/pagefindSearchBar/LogoPagefind.vueAdds Pagefind logo SVG for the modal footer.
packages/vue-components/src/index.jsRegisters the new Search component for <search /> usage.
packages/vue-components/src/tests/Search.spec.jsAdds unit tests for the new Search component behavior.
packages/core/test/unit/utils/data.tsAdds factories/helpers for mocking Pagefind and generating site.json with Pagefind config.
packages/core/test/unit/Site/SiteGenerationManager.test.tsAdds unit tests for Pagefind glob normalization/validation and indexing behavior.
packages/core/src/Site/SitePagesManager.tsInjects Pagefind UI CSS/JS asset paths into page rendering assets when search is enabled.
packages/core/src/Site/SiteGenerationManager.tsAdds Pagefind indexing during site generation and glob filtering support.
packages/core/src/Site/SiteConfig.tsExtends site config to include optional pagefind configuration.
packages/core/src/Page/page.njkInjects Pagefind UI stylesheet/script into generated pages when available.
packages/core/src/Page/PageConfig.tsAdds pagefindCss/pagefindJs to PageAssets type.
packages/core/package.jsonAdds pagefind dependency for build-time indexing.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/UserGuide.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/QuickStart.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/Features.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/FAQ.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/team/johndoe.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/team/AboutUs.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/TracingCode.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Testing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/SettingUp.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Requirements.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Implementation.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Documentation.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/DeveloperGuide.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/DevOps.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Design.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Configuration.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_portfolio/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_minimal/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_table_plugin/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_special_tags/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_3.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/about.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/README.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/Page-1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/Home.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/about.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/_Sidebar.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/_Footer.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/Page-1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/Home.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_algolia_plugin/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/test_md_fragment.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testWeb3FormPlugin.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testVariableContainsInclude.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testTree.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testTooltipSpacing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testThumbnails.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testSourceContainScript.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testSingleAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPopovers.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPopoverTrigger.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPlantUML.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanelsClosingTransition.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanels.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanelMarkdownParsing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavWithoutTitleAndNavHeadings.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavWithOnlyTitle.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavTarget.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavPrint.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNav.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testOcticonInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testModals.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMermaid.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMath.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMaterialIconsInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testList.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLinks.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsWithAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsOverrideWithAltFrontmatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsOverride.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayouts.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludePluginsRendered.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludeMultipleModals.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludeBoilerplate.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testImages.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIconsInSiteLayout.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testHr.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testGlyphiconInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testFontAwesomeInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testExternalScripts.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testEmptyFrontmatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testEmptyAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testDates.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testCodeBlocks.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testCenterText.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testBootstrapIconInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAntiFOUCStyles.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAnnotate.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAnchorGeneration.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAltFrontMatterParsing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAltFrontMatterInvalidKeyValue.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/nested_sub_site/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/nested_sub_site/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/bugs/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/testUtil/compare.tsAdds ignore support for generated Pagefind outputs in functional comparisons.
packages/cli/test/functional/test.tsUses new compare() signature to ignore generated pagefind/ directories.
package-lock.jsonLocks Pagefind and platform-specific optional dependencies.
docs/userGuide/makingTheSiteSearchable.mdDocuments Pagefind beta usage and new site.json options.
.stylelintrc.jsAdds stylelint override for Pagefind UI class naming patterns.
.gitignoreIgnores generated Pagefind directories and fragments.
.eslintrc.jsAdds ESLint ignore patterns for generated/build output directories.
.eslintignoreIgnores generated Pagefind JS under functional test outputs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/core/src/Site/SitePagesManager.ts Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/assets/search.css Outdated
Comment threadpackages/core/src/Site/SiteGenerationManager.ts

@Harjun751Harjun751 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huge effort, and it definitely paid off!

Requesting some changes/clarifications for the

  • debug.log file
  • empty glob parsing
  • windows directory safety check
  • spawned watcher

issues, but other than that it's all minor nits. After the above I think we'll be in a good state.

Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threadpackages/core/src/Page/PageConfig.ts
Comment threadpackages/core/src/Site/SitePagesManager.ts Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts Outdated
Now indexSiteWithPagefind returns a boolean which is then determines if
there is a need to inject the pagefindcss & pagefindJs.
Since isValidGlobPattern is only used by normalizeGlobPattern, changed
it to private access. Now normalization of pattern happens solely in
normalizeGlobPattern and validation is purely a validation method.
Better separation of concerns.
Also resolved a bug where the 404s required pages to be created before
knowing if indexing succeeds by defaulting index success to true and
only if it fails does the flag get set to false.
@gerteck

gerteck commented Mar 22, 2026

Copy link
Copy Markdown
Member

I tried dropping the default pagefind-ui.css and realized the search component is depending on it quite heavily

image

Comment threaddocs/userGuide/makingTheSiteSearchable.md
@gerteck

Copy link
Copy Markdown
Member

Good first step introducing pagefind into MarkBind @MoshiMoshiMochi . The build-time integration (Node API, createIndex/addDirectory/writeFiles, glob support, exclude_selectors config) is solid and the right approach.

The main concern is in Search.vue. The current implementation wraps window.PagefindUI — a pre-built UI component that injects its own DOM, inside a custom modal shell, then works against PagefindUI's behaviour to get the desired result:

  • ~70 lines of :deep(.pagefind-ui__*) CSS overrides to fight PagefindUI's default styles
  • A MutationObserver to detect when PagefindUI renders results (needed because Search.vue has no direct control over PagefindUI's rendering
    lifecycle)
  • Custom keyboard navigation running alongside PagefindUI's own keyboard handling
  • container.innerHTML = '' on modal close as a teardown workaround (PagefindUI has no destroy API)
  • Silent failure if window.PagefindUI is undefined (script load error goes unnoticed)

This is workable for a first cut, but the cause-and-effect is opaque, where future contributors would need to understand both the PagefindUI internals and overrides to make changes safely. It also loads pagefind-ui.js (84.6KB) + pagefind-ui.css (14.5KB) on every page, when we only need pagefind.js (33.8KB).

The long-term direction should be:

  • Replace window.PagefindUI with the lower-level pagefind.js API, which lets you query the index directly and returns plain data objects
  • Ideally, Search.vue owns all the DOM natively as Vue reactive state — no CSS overrides, no MutationObserver, no innerHTML teardown, no global window dependency.

Suggest tracking this as follow-up issues:

  1. Replace window.PagefindUI with pagefind.js lower-level API — remove the <script src="pagefind-ui.js"> global, dynamically import pagefind.js inside the component instead
  2. In-house result rendering — render results natively in the Vue template (title, excerpt, sub-results, active highlight) instead of delegating to PagefindUI's DOM
  3. In-house CSS — replace :deep() overrides with first-party styles scoped to our own markup

I think it is okay to approve as a foundation if these follow-ups are tracked, since the build-time indexing is correct and the search does work end-to-end, just wanted to clarify on your architectural direction for the component moving forward! @MoshiMoshiMochi

@Harjun751Harjun751 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes I requested are addressed 👍

@MoshiMoshiMochi
MoshiMoshiMochi merged commit 19b34fe into MarkBind:masterMar 25, 2026
10 checks passed
@github-actions

Copy link
Copy Markdown

@MoshiMoshiMochi Each PR must have a SEMVER impact label, please remember to label the PR properly.

@gerteckgerteck added the r.Minor Version resolver: increment by 0.1.0 label Mar 26, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

r.MinorVersion resolver: increment by 0.1.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@MoshiMoshiMochi@gerteck@Harjun751
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add PageFind beta V2 (Full Text Search across Site) by MoshiMoshiMochi · Pull Request #2857 · MarkBind/markbind · GitHub
Skip to content

Add PageFind beta V2 (Full Text Search across Site) - #2857

Merged
MoshiMoshiMochi merged 42 commits into
MarkBind:masterfrom
MoshiMoshiMochi:feat/pagefind-beta
Mar 25, 2026
Merged

Add PageFind beta V2 (Full Text Search across Site)#2857
MoshiMoshiMochi merged 42 commits into
MarkBind:masterfrom
MoshiMoshiMochi:feat/pagefind-beta

Conversation

@MoshiMoshiMochi

@MoshiMoshiMochiMoshiMoshiMochi commented Mar 11, 2026

Copy link
Copy Markdown
Contributor

What is the purpose of this pull request?

  • Documentation update
  • Bug fix
  • Feature addition or enhancement
  • Code maintenance
  • DevOps
  • Improve developer experience
  • Others, please explain:

Overview of changes:

Initial version of pagefind (based on #2771)

Original Search Issue is #205

No test cases yet.

Anything you'd like to highlight/discuss:

  1. Created a new Search.vue component <search /> that renders the pagefind search modal.
    • The CSS of which definitely isn't a finish product.
    • Additionally we could consider updating how we present the data.
Heres how the modal currently looks vs Algolia's (CS2103 site)

Current implementation of pagefind.
image

Algolia's styling on CS2103 website
image

From the 2 images above, I believe that Algolia's styling is notably more structured in how it represents the search results and subresults, notably on how they group the search results.

The blog we used as reference for the styling formats the pagefindresults by processing the search results. More information on how to access the specific search results information can be found here.

  1. Added pagefind configuration options within site.json to enable more flexible filtering options. Users can declare
    • exclude_selectors option to exclude specific elements from being searchable.
    • glob option to limit which pages are indexed by Pagefind.
{
"pagefind": {
"exclude_selectors": [".algolia-no-index", "[class*='algolia-no-index']"]
"glob": ["**/devGuide/**", "**/userGuide/**"]
}
}
  • from the example above,
    • exclude_selectors: tells Pagefind to exclude any element with the algolia-no-index class from the searchable results. It works the same way as declaring data-pagefind-ignore.
    • glob: Pagefind will only index pages that are found inside devGuide and userGuide directories (including subdirectories).

All in all, theres still a lot more things we can do to improve this pagefind feature (like page weighting, ranking, sortingetc). But this is all I've managed to conjure up thus far.

Let me know what yall think of these updates to the pagefind feature (there might be better ways to filter pages, this is just from my interpretation when reading through the pagefind docs). Let me know if I missed out on anything in particular or should be focusing my efforts more towards.

  • Definitely going to spend more time working on the styling. But I think if we're gonna process and present our data differently from the base Pagefind UI, then we should probably work on those at the same time since they are intrinsically linked.
  • Also needa write testcases 😔. Not looking forward to that 😢

Testing instructions:

Proposed commit message: (wrap lines at 72 characters)

Add base Pagefind with updated UI & extra filtering functionalities


Checklist: ☑️

  • Updated the documentation for feature additions and enhancements
  • Added tests for bug fixes or features
  • Linked all related issues
  • No unrelated changes

Reviewer checklist:

Indicate the SEMVER impact of the PR:

  • Major (when you make incompatible API changes)
  • Minor (when you add functionality in a backward compatible manner)
  • Patch (when you make backward compatible bug fixes)

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):

  • To be included in the release note for any feature that is made obsolete/breaking

Give a brief explanation note about:

  • what was the old feature that was made obsolete
  • any replacement feature (if any), and
  • how the author should modify his website to migrate from the old feature to the replacement feature (if possible).

This added support for configuring Pagefind search indexing via
site.json is aimed towards allowing users to declare glob patterns to
customize what pages in which directory should be indexed by pagefind.
Initially, I felt that including the root_selector option and
force_language option would be useful for pagefind configuration
options. But perhaps for now it isn't the most pressing issue so I'm
going to exlcude it from the current implementation of pagefind.
This helps resolve an issue with generate() test case within
Site.functional.test.ts. Namely, because Jest's cannot intercept
eval('import("pagefind")') runtime dynamic import used by pagefind.
Hence, for now at least, the error handling would catch this error and
allow the site generation to continue normally.
Extracted processResult into its own helper function.
Added rel="noopener noreferrer" attribute for improved security and
privacy when being redirected to pagefind's github repo.
@codecov

codecovBot commented Mar 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.18321% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.88%. Comparing base (64c1dca) to head (0b71c41).
⚠️ Report is 1 commits behind head on master.

Files with missing linesPatch %Lines
packages/core/src/Site/SiteGenerationManager.ts96.00%3 Missing ⚠️
packages/core/test/unit/utils/data.ts83.33%2 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #2857 +/- ##
==========================================
+ Coverage 70.41% 70.88% +0.47% 
==========================================
Files 129 131 +2 Lines 6952 7083 +131 Branches 1578 1660 +82 ==========================================
+ Hits 4895 5021 +126 - Misses 1957 1962 +5 
Partials 100 100 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@MoshiMoshiMochi

MoshiMoshiMochi commented Mar 19, 2026

Copy link
Copy Markdown
ContributorAuthor

Hi guys, sorry for the wait, marking this as ready to review!

As mentioned in the PR description, while I believe there are still plenty of things that we can work on to enhancing the Pagefind feature in the future.

Namely, we could take a look at

  1. Creating a subsection for our results (similar to how algolia does it, as discussed in last week's meeting). I kinda have an idea of how to extract and process the results information so definitely will work on this as soon as this PR is merged.

  2. Get it to work on hot reloading

We can probably make separate issues for these things.

The current implementation is far from perfect (e.g. a lot of css can be improved, clearly still an issue when using at different browser sizes, also a lot of z level issues with the navbar & nav components).

So let me know of what yall think of the current implementation, anything to improve, anything pressing to fix, etc.

@MarkBind/active-3281-members

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Pagefind-based full-text search to MarkBind as a beta feature, including build-time indexing, asset injection into generated pages, a new Vue <search /> modal UI, and supporting configuration/docs/test updates.

Changes:

  • Introduce a new Vue Search component (Pagefind UI modal) and styling assets.
  • Generate and inject Pagefind search assets during site generation, with site.json support for pagefind.exclude_selectors and pagefind.glob.
  • Update unit/functional tests, expected HTML outputs, and tooling ignores to accommodate generated Pagefind artifacts.

Reviewed changes

Copilot reviewed 128 out of 130 changed files in this pull request and generated 10 comments.

Show a summary per file
FileDescription
packages/vue-components/src/pagefindSearchBar/assets/search.cssAdds global CSS for the Pagefind search modal styling.
packages/vue-components/src/pagefindSearchBar/Search.vueNew Pagefind-backed search modal component + keyboard handling and UI overrides.
packages/vue-components/src/pagefindSearchBar/LogoPagefind.vueAdds Pagefind logo SVG for the modal footer.
packages/vue-components/src/index.jsRegisters the new Search component for <search /> usage.
packages/vue-components/src/tests/Search.spec.jsAdds unit tests for the new Search component behavior.
packages/core/test/unit/utils/data.tsAdds factories/helpers for mocking Pagefind and generating site.json with Pagefind config.
packages/core/test/unit/Site/SiteGenerationManager.test.tsAdds unit tests for Pagefind glob normalization/validation and indexing behavior.
packages/core/src/Site/SitePagesManager.tsInjects Pagefind UI CSS/JS asset paths into page rendering assets when search is enabled.
packages/core/src/Site/SiteGenerationManager.tsAdds Pagefind indexing during site generation and glob filtering support.
packages/core/src/Site/SiteConfig.tsExtends site config to include optional pagefind configuration.
packages/core/src/Page/page.njkInjects Pagefind UI stylesheet/script into generated pages when available.
packages/core/src/Page/PageConfig.tsAdds pagefindCss/pagefindJs to PageAssets type.
packages/core/package.jsonAdds pagefind dependency for build-time indexing.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/UserGuide.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/QuickStart.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/Features.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/FAQ.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/team/johndoe.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/team/AboutUs.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/TracingCode.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Testing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/SettingUp.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Requirements.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Implementation.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Documentation.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/DeveloperGuide.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/DevOps.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Design.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Configuration.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_portfolio/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_minimal/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_table_plugin/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_special_tags/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_3.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/about.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/README.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/Page-1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/Home.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/about.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/_Sidebar.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/_Footer.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/Page-1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/Home.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_algolia_plugin/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/test_md_fragment.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testWeb3FormPlugin.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testVariableContainsInclude.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testTree.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testTooltipSpacing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testThumbnails.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testSourceContainScript.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testSingleAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPopovers.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPopoverTrigger.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPlantUML.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanelsClosingTransition.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanels.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanelMarkdownParsing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavWithoutTitleAndNavHeadings.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavWithOnlyTitle.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavTarget.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavPrint.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNav.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testOcticonInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testModals.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMermaid.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMath.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMaterialIconsInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testList.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLinks.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsWithAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsOverrideWithAltFrontmatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsOverride.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayouts.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludePluginsRendered.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludeMultipleModals.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludeBoilerplate.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testImages.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIconsInSiteLayout.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testHr.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testGlyphiconInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testFontAwesomeInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testExternalScripts.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testEmptyFrontmatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testEmptyAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testDates.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testCodeBlocks.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testCenterText.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testBootstrapIconInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAntiFOUCStyles.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAnnotate.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAnchorGeneration.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAltFrontMatterParsing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAltFrontMatterInvalidKeyValue.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/nested_sub_site/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/nested_sub_site/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/bugs/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/testUtil/compare.tsAdds ignore support for generated Pagefind outputs in functional comparisons.
packages/cli/test/functional/test.tsUses new compare() signature to ignore generated pagefind/ directories.
package-lock.jsonLocks Pagefind and platform-specific optional dependencies.
docs/userGuide/makingTheSiteSearchable.mdDocuments Pagefind beta usage and new site.json options.
.stylelintrc.jsAdds stylelint override for Pagefind UI class naming patterns.
.gitignoreIgnores generated Pagefind directories and fragments.
.eslintrc.jsAdds ESLint ignore patterns for generated/build output directories.
.eslintignoreIgnores generated Pagefind JS under functional test outputs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/core/src/Site/SitePagesManager.ts Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/assets/search.css Outdated
Comment threadpackages/core/src/Site/SiteGenerationManager.ts

@Harjun751Harjun751 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huge effort, and it definitely paid off!

Requesting some changes/clarifications for the

  • debug.log file
  • empty glob parsing
  • windows directory safety check
  • spawned watcher

issues, but other than that it's all minor nits. After the above I think we'll be in a good state.

Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threadpackages/core/src/Page/PageConfig.ts
Comment threadpackages/core/src/Site/SitePagesManager.ts Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts Outdated
Now indexSiteWithPagefind returns a boolean which is then determines if
there is a need to inject the pagefindcss & pagefindJs.
Since isValidGlobPattern is only used by normalizeGlobPattern, changed
it to private access. Now normalization of pattern happens solely in
normalizeGlobPattern and validation is purely a validation method.
Better separation of concerns.
Also resolved a bug where the 404s required pages to be created before
knowing if indexing succeeds by defaulting index success to true and
only if it fails does the flag get set to false.
@gerteck

gerteck commented Mar 22, 2026

Copy link
Copy Markdown
Member

I tried dropping the default pagefind-ui.css and realized the search component is depending on it quite heavily

image

Comment threaddocs/userGuide/makingTheSiteSearchable.md
@gerteck

Copy link
Copy Markdown
Member

Good first step introducing pagefind into MarkBind @MoshiMoshiMochi . The build-time integration (Node API, createIndex/addDirectory/writeFiles, glob support, exclude_selectors config) is solid and the right approach.

The main concern is in Search.vue. The current implementation wraps window.PagefindUI — a pre-built UI component that injects its own DOM, inside a custom modal shell, then works against PagefindUI's behaviour to get the desired result:

  • ~70 lines of :deep(.pagefind-ui__*) CSS overrides to fight PagefindUI's default styles
  • A MutationObserver to detect when PagefindUI renders results (needed because Search.vue has no direct control over PagefindUI's rendering
    lifecycle)
  • Custom keyboard navigation running alongside PagefindUI's own keyboard handling
  • container.innerHTML = '' on modal close as a teardown workaround (PagefindUI has no destroy API)
  • Silent failure if window.PagefindUI is undefined (script load error goes unnoticed)

This is workable for a first cut, but the cause-and-effect is opaque, where future contributors would need to understand both the PagefindUI internals and overrides to make changes safely. It also loads pagefind-ui.js (84.6KB) + pagefind-ui.css (14.5KB) on every page, when we only need pagefind.js (33.8KB).

The long-term direction should be:

  • Replace window.PagefindUI with the lower-level pagefind.js API, which lets you query the index directly and returns plain data objects
  • Ideally, Search.vue owns all the DOM natively as Vue reactive state — no CSS overrides, no MutationObserver, no innerHTML teardown, no global window dependency.

Suggest tracking this as follow-up issues:

  1. Replace window.PagefindUI with pagefind.js lower-level API — remove the <script src="pagefind-ui.js"> global, dynamically import pagefind.js inside the component instead
  2. In-house result rendering — render results natively in the Vue template (title, excerpt, sub-results, active highlight) instead of delegating to PagefindUI's DOM
  3. In-house CSS — replace :deep() overrides with first-party styles scoped to our own markup

I think it is okay to approve as a foundation if these follow-ups are tracked, since the build-time indexing is correct and the search does work end-to-end, just wanted to clarify on your architectural direction for the component moving forward! @MoshiMoshiMochi

@Harjun751Harjun751 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes I requested are addressed 👍

@MoshiMoshiMochi
MoshiMoshiMochi merged commit 19b34fe into MarkBind:masterMar 25, 2026
10 checks passed
@github-actions

Copy link
Copy Markdown

@MoshiMoshiMochi Each PR must have a SEMVER impact label, please remember to label the PR properly.

@gerteckgerteck added the r.Minor Version resolver: increment by 0.1.0 label Mar 26, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

r.MinorVersion resolver: increment by 0.1.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@MoshiMoshiMochi@gerteck@Harjun751
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add PageFind beta V2 (Full Text Search across Site) by MoshiMoshiMochi · Pull Request #2857 · MarkBind/markbind · GitHub
Skip to content

Add PageFind beta V2 (Full Text Search across Site) - #2857

Merged
MoshiMoshiMochi merged 42 commits into
MarkBind:masterfrom
MoshiMoshiMochi:feat/pagefind-beta
Mar 25, 2026
Merged

Add PageFind beta V2 (Full Text Search across Site)#2857
MoshiMoshiMochi merged 42 commits into
MarkBind:masterfrom
MoshiMoshiMochi:feat/pagefind-beta

Conversation

@MoshiMoshiMochi

@MoshiMoshiMochiMoshiMoshiMochi commented Mar 11, 2026

Copy link
Copy Markdown
Contributor

What is the purpose of this pull request?

  • Documentation update
  • Bug fix
  • Feature addition or enhancement
  • Code maintenance
  • DevOps
  • Improve developer experience
  • Others, please explain:

Overview of changes:

Initial version of pagefind (based on #2771)

Original Search Issue is #205

No test cases yet.

Anything you'd like to highlight/discuss:

  1. Created a new Search.vue component <search /> that renders the pagefind search modal.
    • The CSS of which definitely isn't a finish product.
    • Additionally we could consider updating how we present the data.
Heres how the modal currently looks vs Algolia's (CS2103 site)

Current implementation of pagefind.
image

Algolia's styling on CS2103 website
image

From the 2 images above, I believe that Algolia's styling is notably more structured in how it represents the search results and subresults, notably on how they group the search results.

The blog we used as reference for the styling formats the pagefindresults by processing the search results. More information on how to access the specific search results information can be found here.

  1. Added pagefind configuration options within site.json to enable more flexible filtering options. Users can declare
    • exclude_selectors option to exclude specific elements from being searchable.
    • glob option to limit which pages are indexed by Pagefind.
{
"pagefind": {
"exclude_selectors": [".algolia-no-index", "[class*='algolia-no-index']"]
"glob": ["**/devGuide/**", "**/userGuide/**"]
}
}
  • from the example above,
    • exclude_selectors: tells Pagefind to exclude any element with the algolia-no-index class from the searchable results. It works the same way as declaring data-pagefind-ignore.
    • glob: Pagefind will only index pages that are found inside devGuide and userGuide directories (including subdirectories).

All in all, theres still a lot more things we can do to improve this pagefind feature (like page weighting, ranking, sortingetc). But this is all I've managed to conjure up thus far.

Let me know what yall think of these updates to the pagefind feature (there might be better ways to filter pages, this is just from my interpretation when reading through the pagefind docs). Let me know if I missed out on anything in particular or should be focusing my efforts more towards.

  • Definitely going to spend more time working on the styling. But I think if we're gonna process and present our data differently from the base Pagefind UI, then we should probably work on those at the same time since they are intrinsically linked.
  • Also needa write testcases 😔. Not looking forward to that 😢

Testing instructions:

Proposed commit message: (wrap lines at 72 characters)

Add base Pagefind with updated UI & extra filtering functionalities


Checklist: ☑️

  • Updated the documentation for feature additions and enhancements
  • Added tests for bug fixes or features
  • Linked all related issues
  • No unrelated changes

Reviewer checklist:

Indicate the SEMVER impact of the PR:

  • Major (when you make incompatible API changes)
  • Minor (when you add functionality in a backward compatible manner)
  • Patch (when you make backward compatible bug fixes)

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):

  • To be included in the release note for any feature that is made obsolete/breaking

Give a brief explanation note about:

  • what was the old feature that was made obsolete
  • any replacement feature (if any), and
  • how the author should modify his website to migrate from the old feature to the replacement feature (if possible).

This added support for configuring Pagefind search indexing via
site.json is aimed towards allowing users to declare glob patterns to
customize what pages in which directory should be indexed by pagefind.
Initially, I felt that including the root_selector option and
force_language option would be useful for pagefind configuration
options. But perhaps for now it isn't the most pressing issue so I'm
going to exlcude it from the current implementation of pagefind.
This helps resolve an issue with generate() test case within
Site.functional.test.ts. Namely, because Jest's cannot intercept
eval('import("pagefind")') runtime dynamic import used by pagefind.
Hence, for now at least, the error handling would catch this error and
allow the site generation to continue normally.
Extracted processResult into its own helper function.
Added rel="noopener noreferrer" attribute for improved security and
privacy when being redirected to pagefind's github repo.
@codecov

codecovBot commented Mar 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.18321% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.88%. Comparing base (64c1dca) to head (0b71c41).
⚠️ Report is 1 commits behind head on master.

Files with missing linesPatch %Lines
packages/core/src/Site/SiteGenerationManager.ts96.00%3 Missing ⚠️
packages/core/test/unit/utils/data.ts83.33%2 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #2857 +/- ##
==========================================
+ Coverage 70.41% 70.88% +0.47% 
==========================================
Files 129 131 +2 Lines 6952 7083 +131 Branches 1578 1660 +82 ==========================================
+ Hits 4895 5021 +126 - Misses 1957 1962 +5 
Partials 100 100 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@MoshiMoshiMochi

MoshiMoshiMochi commented Mar 19, 2026

Copy link
Copy Markdown
ContributorAuthor

Hi guys, sorry for the wait, marking this as ready to review!

As mentioned in the PR description, while I believe there are still plenty of things that we can work on to enhancing the Pagefind feature in the future.

Namely, we could take a look at

  1. Creating a subsection for our results (similar to how algolia does it, as discussed in last week's meeting). I kinda have an idea of how to extract and process the results information so definitely will work on this as soon as this PR is merged.

  2. Get it to work on hot reloading

We can probably make separate issues for these things.

The current implementation is far from perfect (e.g. a lot of css can be improved, clearly still an issue when using at different browser sizes, also a lot of z level issues with the navbar & nav components).

So let me know of what yall think of the current implementation, anything to improve, anything pressing to fix, etc.

@MarkBind/active-3281-members

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Pagefind-based full-text search to MarkBind as a beta feature, including build-time indexing, asset injection into generated pages, a new Vue <search /> modal UI, and supporting configuration/docs/test updates.

Changes:

  • Introduce a new Vue Search component (Pagefind UI modal) and styling assets.
  • Generate and inject Pagefind search assets during site generation, with site.json support for pagefind.exclude_selectors and pagefind.glob.
  • Update unit/functional tests, expected HTML outputs, and tooling ignores to accommodate generated Pagefind artifacts.

Reviewed changes

Copilot reviewed 128 out of 130 changed files in this pull request and generated 10 comments.

Show a summary per file
FileDescription
packages/vue-components/src/pagefindSearchBar/assets/search.cssAdds global CSS for the Pagefind search modal styling.
packages/vue-components/src/pagefindSearchBar/Search.vueNew Pagefind-backed search modal component + keyboard handling and UI overrides.
packages/vue-components/src/pagefindSearchBar/LogoPagefind.vueAdds Pagefind logo SVG for the modal footer.
packages/vue-components/src/index.jsRegisters the new Search component for <search /> usage.
packages/vue-components/src/tests/Search.spec.jsAdds unit tests for the new Search component behavior.
packages/core/test/unit/utils/data.tsAdds factories/helpers for mocking Pagefind and generating site.json with Pagefind config.
packages/core/test/unit/Site/SiteGenerationManager.test.tsAdds unit tests for Pagefind glob normalization/validation and indexing behavior.
packages/core/src/Site/SitePagesManager.tsInjects Pagefind UI CSS/JS asset paths into page rendering assets when search is enabled.
packages/core/src/Site/SiteGenerationManager.tsAdds Pagefind indexing during site generation and glob filtering support.
packages/core/src/Site/SiteConfig.tsExtends site config to include optional pagefind configuration.
packages/core/src/Page/page.njkInjects Pagefind UI stylesheet/script into generated pages when available.
packages/core/src/Page/PageConfig.tsAdds pagefindCss/pagefindJs to PageAssets type.
packages/core/package.jsonAdds pagefind dependency for build-time indexing.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/UserGuide.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/QuickStart.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/Features.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/FAQ.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/team/johndoe.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/team/AboutUs.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/TracingCode.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Testing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/SettingUp.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Requirements.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Implementation.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Documentation.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/DeveloperGuide.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/DevOps.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Design.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Configuration.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_portfolio/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_minimal/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_table_plugin/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_special_tags/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_3.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/about.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/README.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/Page-1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/Home.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/about.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/_Sidebar.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/_Footer.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/Page-1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/Home.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_algolia_plugin/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/test_md_fragment.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testWeb3FormPlugin.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testVariableContainsInclude.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testTree.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testTooltipSpacing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testThumbnails.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testSourceContainScript.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testSingleAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPopovers.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPopoverTrigger.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPlantUML.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanelsClosingTransition.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanels.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanelMarkdownParsing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavWithoutTitleAndNavHeadings.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavWithOnlyTitle.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavTarget.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavPrint.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNav.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testOcticonInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testModals.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMermaid.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMath.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMaterialIconsInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testList.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLinks.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsWithAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsOverrideWithAltFrontmatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsOverride.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayouts.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludePluginsRendered.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludeMultipleModals.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludeBoilerplate.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testImages.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIconsInSiteLayout.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testHr.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testGlyphiconInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testFontAwesomeInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testExternalScripts.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testEmptyFrontmatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testEmptyAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testDates.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testCodeBlocks.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testCenterText.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testBootstrapIconInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAntiFOUCStyles.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAnnotate.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAnchorGeneration.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAltFrontMatterParsing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAltFrontMatterInvalidKeyValue.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/nested_sub_site/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/nested_sub_site/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/bugs/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/testUtil/compare.tsAdds ignore support for generated Pagefind outputs in functional comparisons.
packages/cli/test/functional/test.tsUses new compare() signature to ignore generated pagefind/ directories.
package-lock.jsonLocks Pagefind and platform-specific optional dependencies.
docs/userGuide/makingTheSiteSearchable.mdDocuments Pagefind beta usage and new site.json options.
.stylelintrc.jsAdds stylelint override for Pagefind UI class naming patterns.
.gitignoreIgnores generated Pagefind directories and fragments.
.eslintrc.jsAdds ESLint ignore patterns for generated/build output directories.
.eslintignoreIgnores generated Pagefind JS under functional test outputs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/core/src/Site/SitePagesManager.ts Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/assets/search.css Outdated
Comment threadpackages/core/src/Site/SiteGenerationManager.ts

@Harjun751Harjun751 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huge effort, and it definitely paid off!

Requesting some changes/clarifications for the

  • debug.log file
  • empty glob parsing
  • windows directory safety check
  • spawned watcher

issues, but other than that it's all minor nits. After the above I think we'll be in a good state.

Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threadpackages/core/src/Page/PageConfig.ts
Comment threadpackages/core/src/Site/SitePagesManager.ts Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts Outdated
Now indexSiteWithPagefind returns a boolean which is then determines if
there is a need to inject the pagefindcss & pagefindJs.
Since isValidGlobPattern is only used by normalizeGlobPattern, changed
it to private access. Now normalization of pattern happens solely in
normalizeGlobPattern and validation is purely a validation method.
Better separation of concerns.
Also resolved a bug where the 404s required pages to be created before
knowing if indexing succeeds by defaulting index success to true and
only if it fails does the flag get set to false.
@gerteck

gerteck commented Mar 22, 2026

Copy link
Copy Markdown
Member

I tried dropping the default pagefind-ui.css and realized the search component is depending on it quite heavily

image

Comment threaddocs/userGuide/makingTheSiteSearchable.md
@gerteck

Copy link
Copy Markdown
Member

Good first step introducing pagefind into MarkBind @MoshiMoshiMochi . The build-time integration (Node API, createIndex/addDirectory/writeFiles, glob support, exclude_selectors config) is solid and the right approach.

The main concern is in Search.vue. The current implementation wraps window.PagefindUI — a pre-built UI component that injects its own DOM, inside a custom modal shell, then works against PagefindUI's behaviour to get the desired result:

  • ~70 lines of :deep(.pagefind-ui__*) CSS overrides to fight PagefindUI's default styles
  • A MutationObserver to detect when PagefindUI renders results (needed because Search.vue has no direct control over PagefindUI's rendering
    lifecycle)
  • Custom keyboard navigation running alongside PagefindUI's own keyboard handling
  • container.innerHTML = '' on modal close as a teardown workaround (PagefindUI has no destroy API)
  • Silent failure if window.PagefindUI is undefined (script load error goes unnoticed)

This is workable for a first cut, but the cause-and-effect is opaque, where future contributors would need to understand both the PagefindUI internals and overrides to make changes safely. It also loads pagefind-ui.js (84.6KB) + pagefind-ui.css (14.5KB) on every page, when we only need pagefind.js (33.8KB).

The long-term direction should be:

  • Replace window.PagefindUI with the lower-level pagefind.js API, which lets you query the index directly and returns plain data objects
  • Ideally, Search.vue owns all the DOM natively as Vue reactive state — no CSS overrides, no MutationObserver, no innerHTML teardown, no global window dependency.

Suggest tracking this as follow-up issues:

  1. Replace window.PagefindUI with pagefind.js lower-level API — remove the <script src="pagefind-ui.js"> global, dynamically import pagefind.js inside the component instead
  2. In-house result rendering — render results natively in the Vue template (title, excerpt, sub-results, active highlight) instead of delegating to PagefindUI's DOM
  3. In-house CSS — replace :deep() overrides with first-party styles scoped to our own markup

I think it is okay to approve as a foundation if these follow-ups are tracked, since the build-time indexing is correct and the search does work end-to-end, just wanted to clarify on your architectural direction for the component moving forward! @MoshiMoshiMochi

@Harjun751Harjun751 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes I requested are addressed 👍

@MoshiMoshiMochi
MoshiMoshiMochi merged commit 19b34fe into MarkBind:masterMar 25, 2026
10 checks passed
@github-actions

Copy link
Copy Markdown

@MoshiMoshiMochi Each PR must have a SEMVER impact label, please remember to label the PR properly.

@gerteckgerteck added the r.Minor Version resolver: increment by 0.1.0 label Mar 26, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

r.MinorVersion resolver: increment by 0.1.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@MoshiMoshiMochi@gerteck@Harjun751
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Add PageFind beta V2 (Full Text Search across Site) by MoshiMoshiMochi · Pull Request #2857 · MarkBind/markbind · GitHub
Skip to content

Add PageFind beta V2 (Full Text Search across Site) - #2857

Merged
MoshiMoshiMochi merged 42 commits into
MarkBind:masterfrom
MoshiMoshiMochi:feat/pagefind-beta
Mar 25, 2026
Merged

Add PageFind beta V2 (Full Text Search across Site)#2857
MoshiMoshiMochi merged 42 commits into
MarkBind:masterfrom
MoshiMoshiMochi:feat/pagefind-beta

Conversation

@MoshiMoshiMochi

@MoshiMoshiMochiMoshiMoshiMochi commented Mar 11, 2026

Copy link
Copy Markdown
Contributor

What is the purpose of this pull request?

  • Documentation update
  • Bug fix
  • Feature addition or enhancement
  • Code maintenance
  • DevOps
  • Improve developer experience
  • Others, please explain:

Overview of changes:

Initial version of pagefind (based on #2771)

Original Search Issue is #205

No test cases yet.

Anything you'd like to highlight/discuss:

  1. Created a new Search.vue component <search /> that renders the pagefind search modal.
    • The CSS of which definitely isn't a finish product.
    • Additionally we could consider updating how we present the data.
Heres how the modal currently looks vs Algolia's (CS2103 site)

Current implementation of pagefind.
image

Algolia's styling on CS2103 website
image

From the 2 images above, I believe that Algolia's styling is notably more structured in how it represents the search results and subresults, notably on how they group the search results.

The blog we used as reference for the styling formats the pagefindresults by processing the search results. More information on how to access the specific search results information can be found here.

  1. Added pagefind configuration options within site.json to enable more flexible filtering options. Users can declare
    • exclude_selectors option to exclude specific elements from being searchable.
    • glob option to limit which pages are indexed by Pagefind.
{
"pagefind": {
"exclude_selectors": [".algolia-no-index", "[class*='algolia-no-index']"]
"glob": ["**/devGuide/**", "**/userGuide/**"]
}
}
  • from the example above,
    • exclude_selectors: tells Pagefind to exclude any element with the algolia-no-index class from the searchable results. It works the same way as declaring data-pagefind-ignore.
    • glob: Pagefind will only index pages that are found inside devGuide and userGuide directories (including subdirectories).

All in all, theres still a lot more things we can do to improve this pagefind feature (like page weighting, ranking, sortingetc). But this is all I've managed to conjure up thus far.

Let me know what yall think of these updates to the pagefind feature (there might be better ways to filter pages, this is just from my interpretation when reading through the pagefind docs). Let me know if I missed out on anything in particular or should be focusing my efforts more towards.

  • Definitely going to spend more time working on the styling. But I think if we're gonna process and present our data differently from the base Pagefind UI, then we should probably work on those at the same time since they are intrinsically linked.
  • Also needa write testcases 😔. Not looking forward to that 😢

Testing instructions:

Proposed commit message: (wrap lines at 72 characters)

Add base Pagefind with updated UI & extra filtering functionalities


Checklist: ☑️

  • Updated the documentation for feature additions and enhancements
  • Added tests for bug fixes or features
  • Linked all related issues
  • No unrelated changes

Reviewer checklist:

Indicate the SEMVER impact of the PR:

  • Major (when you make incompatible API changes)
  • Minor (when you add functionality in a backward compatible manner)
  • Patch (when you make backward compatible bug fixes)

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):

  • To be included in the release note for any feature that is made obsolete/breaking

Give a brief explanation note about:

  • what was the old feature that was made obsolete
  • any replacement feature (if any), and
  • how the author should modify his website to migrate from the old feature to the replacement feature (if possible).

This added support for configuring Pagefind search indexing via
site.json is aimed towards allowing users to declare glob patterns to
customize what pages in which directory should be indexed by pagefind.
Initially, I felt that including the root_selector option and
force_language option would be useful for pagefind configuration
options. But perhaps for now it isn't the most pressing issue so I'm
going to exlcude it from the current implementation of pagefind.
This helps resolve an issue with generate() test case within
Site.functional.test.ts. Namely, because Jest's cannot intercept
eval('import("pagefind")') runtime dynamic import used by pagefind.
Hence, for now at least, the error handling would catch this error and
allow the site generation to continue normally.
Extracted processResult into its own helper function.
Added rel="noopener noreferrer" attribute for improved security and
privacy when being redirected to pagefind's github repo.
@codecov

codecovBot commented Mar 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.18321% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.88%. Comparing base (64c1dca) to head (0b71c41).
⚠️ Report is 1 commits behind head on master.

Files with missing linesPatch %Lines
packages/core/src/Site/SiteGenerationManager.ts96.00%3 Missing ⚠️
packages/core/test/unit/utils/data.ts83.33%2 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #2857 +/- ##
==========================================
+ Coverage 70.41% 70.88% +0.47% 
==========================================
Files 129 131 +2 Lines 6952 7083 +131 Branches 1578 1660 +82 ==========================================
+ Hits 4895 5021 +126 - Misses 1957 1962 +5 
Partials 100 100 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@MoshiMoshiMochi

MoshiMoshiMochi commented Mar 19, 2026

Copy link
Copy Markdown
ContributorAuthor

Hi guys, sorry for the wait, marking this as ready to review!

As mentioned in the PR description, while I believe there are still plenty of things that we can work on to enhancing the Pagefind feature in the future.

Namely, we could take a look at

  1. Creating a subsection for our results (similar to how algolia does it, as discussed in last week's meeting). I kinda have an idea of how to extract and process the results information so definitely will work on this as soon as this PR is merged.

  2. Get it to work on hot reloading

We can probably make separate issues for these things.

The current implementation is far from perfect (e.g. a lot of css can be improved, clearly still an issue when using at different browser sizes, also a lot of z level issues with the navbar & nav components).

So let me know of what yall think of the current implementation, anything to improve, anything pressing to fix, etc.

@MarkBind/active-3281-members

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Pagefind-based full-text search to MarkBind as a beta feature, including build-time indexing, asset injection into generated pages, a new Vue <search /> modal UI, and supporting configuration/docs/test updates.

Changes:

  • Introduce a new Vue Search component (Pagefind UI modal) and styling assets.
  • Generate and inject Pagefind search assets during site generation, with site.json support for pagefind.exclude_selectors and pagefind.glob.
  • Update unit/functional tests, expected HTML outputs, and tooling ignores to accommodate generated Pagefind artifacts.

Reviewed changes

Copilot reviewed 128 out of 130 changed files in this pull request and generated 10 comments.

Show a summary per file
FileDescription
packages/vue-components/src/pagefindSearchBar/assets/search.cssAdds global CSS for the Pagefind search modal styling.
packages/vue-components/src/pagefindSearchBar/Search.vueNew Pagefind-backed search modal component + keyboard handling and UI overrides.
packages/vue-components/src/pagefindSearchBar/LogoPagefind.vueAdds Pagefind logo SVG for the modal footer.
packages/vue-components/src/index.jsRegisters the new Search component for <search /> usage.
packages/vue-components/src/tests/Search.spec.jsAdds unit tests for the new Search component behavior.
packages/core/test/unit/utils/data.tsAdds factories/helpers for mocking Pagefind and generating site.json with Pagefind config.
packages/core/test/unit/Site/SiteGenerationManager.test.tsAdds unit tests for Pagefind glob normalization/validation and indexing behavior.
packages/core/src/Site/SitePagesManager.tsInjects Pagefind UI CSS/JS asset paths into page rendering assets when search is enabled.
packages/core/src/Site/SiteGenerationManager.tsAdds Pagefind indexing during site generation and glob filtering support.
packages/core/src/Site/SiteConfig.tsExtends site config to include optional pagefind configuration.
packages/core/src/Page/page.njkInjects Pagefind UI stylesheet/script into generated pages when available.
packages/core/src/Page/PageConfig.tsAdds pagefindCss/pagefindJs to PageAssets type.
packages/core/package.jsonAdds pagefind dependency for build-time indexing.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/UserGuide.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/QuickStart.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/Features.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/FAQ.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/team/johndoe.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/team/AboutUs.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/TracingCode.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Testing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/SettingUp.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Requirements.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Implementation.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Documentation.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/DeveloperGuide.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/DevOps.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Design.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Configuration.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_portfolio/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_minimal/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_table_plugin/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_special_tags/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_3.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/about.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/README.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/Page-1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/Home.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/about.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/_Sidebar.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/_Footer.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/Page-1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/Home.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_algolia_plugin/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/test_md_fragment.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testWeb3FormPlugin.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testVariableContainsInclude.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testTree.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testTooltipSpacing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testThumbnails.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testSourceContainScript.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testSingleAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPopovers.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPopoverTrigger.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPlantUML.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanelsClosingTransition.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanels.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanelMarkdownParsing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavWithoutTitleAndNavHeadings.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavWithOnlyTitle.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavTarget.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavPrint.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNav.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testOcticonInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testModals.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMermaid.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMath.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMaterialIconsInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testList.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLinks.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsWithAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsOverrideWithAltFrontmatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsOverride.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayouts.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludePluginsRendered.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludeMultipleModals.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludeBoilerplate.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testImages.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIconsInSiteLayout.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testHr.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testGlyphiconInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testFontAwesomeInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testExternalScripts.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testEmptyFrontmatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testEmptyAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testDates.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testCodeBlocks.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testCenterText.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testBootstrapIconInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAntiFOUCStyles.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAnnotate.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAnchorGeneration.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAltFrontMatterParsing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAltFrontMatterInvalidKeyValue.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/nested_sub_site/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/nested_sub_site/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/bugs/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/testUtil/compare.tsAdds ignore support for generated Pagefind outputs in functional comparisons.
packages/cli/test/functional/test.tsUses new compare() signature to ignore generated pagefind/ directories.
package-lock.jsonLocks Pagefind and platform-specific optional dependencies.
docs/userGuide/makingTheSiteSearchable.mdDocuments Pagefind beta usage and new site.json options.
.stylelintrc.jsAdds stylelint override for Pagefind UI class naming patterns.
.gitignoreIgnores generated Pagefind directories and fragments.
.eslintrc.jsAdds ESLint ignore patterns for generated/build output directories.
.eslintignoreIgnores generated Pagefind JS under functional test outputs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/core/src/Site/SitePagesManager.ts Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/assets/search.css Outdated
Comment threadpackages/core/src/Site/SiteGenerationManager.ts

@Harjun751Harjun751 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huge effort, and it definitely paid off!

Requesting some changes/clarifications for the

  • debug.log file
  • empty glob parsing
  • windows directory safety check
  • spawned watcher

issues, but other than that it's all minor nits. After the above I think we'll be in a good state.

Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threadpackages/core/src/Page/PageConfig.ts
Comment threadpackages/core/src/Site/SitePagesManager.ts Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts Outdated
Now indexSiteWithPagefind returns a boolean which is then determines if
there is a need to inject the pagefindcss & pagefindJs.
Since isValidGlobPattern is only used by normalizeGlobPattern, changed
it to private access. Now normalization of pattern happens solely in
normalizeGlobPattern and validation is purely a validation method.
Better separation of concerns.
Also resolved a bug where the 404s required pages to be created before
knowing if indexing succeeds by defaulting index success to true and
only if it fails does the flag get set to false.
@gerteck

gerteck commented Mar 22, 2026

Copy link
Copy Markdown
Member

I tried dropping the default pagefind-ui.css and realized the search component is depending on it quite heavily

image

Comment threaddocs/userGuide/makingTheSiteSearchable.md
@gerteck

Copy link
Copy Markdown
Member

Good first step introducing pagefind into MarkBind @MoshiMoshiMochi . The build-time integration (Node API, createIndex/addDirectory/writeFiles, glob support, exclude_selectors config) is solid and the right approach.

The main concern is in Search.vue. The current implementation wraps window.PagefindUI — a pre-built UI component that injects its own DOM, inside a custom modal shell, then works against PagefindUI's behaviour to get the desired result:

  • ~70 lines of :deep(.pagefind-ui__*) CSS overrides to fight PagefindUI's default styles
  • A MutationObserver to detect when PagefindUI renders results (needed because Search.vue has no direct control over PagefindUI's rendering
    lifecycle)
  • Custom keyboard navigation running alongside PagefindUI's own keyboard handling
  • container.innerHTML = '' on modal close as a teardown workaround (PagefindUI has no destroy API)
  • Silent failure if window.PagefindUI is undefined (script load error goes unnoticed)

This is workable for a first cut, but the cause-and-effect is opaque, where future contributors would need to understand both the PagefindUI internals and overrides to make changes safely. It also loads pagefind-ui.js (84.6KB) + pagefind-ui.css (14.5KB) on every page, when we only need pagefind.js (33.8KB).

The long-term direction should be:

  • Replace window.PagefindUI with the lower-level pagefind.js API, which lets you query the index directly and returns plain data objects
  • Ideally, Search.vue owns all the DOM natively as Vue reactive state — no CSS overrides, no MutationObserver, no innerHTML teardown, no global window dependency.

Suggest tracking this as follow-up issues:

  1. Replace window.PagefindUI with pagefind.js lower-level API — remove the <script src="pagefind-ui.js"> global, dynamically import pagefind.js inside the component instead
  2. In-house result rendering — render results natively in the Vue template (title, excerpt, sub-results, active highlight) instead of delegating to PagefindUI's DOM
  3. In-house CSS — replace :deep() overrides with first-party styles scoped to our own markup

I think it is okay to approve as a foundation if these follow-ups are tracked, since the build-time indexing is correct and the search does work end-to-end, just wanted to clarify on your architectural direction for the component moving forward! @MoshiMoshiMochi

@Harjun751Harjun751 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes I requested are addressed 👍

@MoshiMoshiMochi
MoshiMoshiMochi merged commit 19b34fe into MarkBind:masterMar 25, 2026
10 checks passed
@github-actions

Copy link
Copy Markdown

@MoshiMoshiMochi Each PR must have a SEMVER impact label, please remember to label the PR properly.

@gerteckgerteck added the r.Minor Version resolver: increment by 0.1.0 label Mar 26, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

r.MinorVersion resolver: increment by 0.1.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@MoshiMoshiMochi@gerteck@Harjun751
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add PageFind beta V2 (Full Text Search across Site) by MoshiMoshiMochi · Pull Request #2857 · MarkBind/markbind · GitHub
Skip to content

Add PageFind beta V2 (Full Text Search across Site) - #2857

Merged
MoshiMoshiMochi merged 42 commits into
MarkBind:masterfrom
MoshiMoshiMochi:feat/pagefind-beta
Mar 25, 2026
Merged

Add PageFind beta V2 (Full Text Search across Site)#2857
MoshiMoshiMochi merged 42 commits into
MarkBind:masterfrom
MoshiMoshiMochi:feat/pagefind-beta

Conversation

@MoshiMoshiMochi

@MoshiMoshiMochiMoshiMoshiMochi commented Mar 11, 2026

Copy link
Copy Markdown
Contributor

What is the purpose of this pull request?

  • Documentation update
  • Bug fix
  • Feature addition or enhancement
  • Code maintenance
  • DevOps
  • Improve developer experience
  • Others, please explain:

Overview of changes:

Initial version of pagefind (based on #2771)

Original Search Issue is #205

No test cases yet.

Anything you'd like to highlight/discuss:

  1. Created a new Search.vue component <search /> that renders the pagefind search modal.
    • The CSS of which definitely isn't a finish product.
    • Additionally we could consider updating how we present the data.
Heres how the modal currently looks vs Algolia's (CS2103 site)

Current implementation of pagefind.
image

Algolia's styling on CS2103 website
image

From the 2 images above, I believe that Algolia's styling is notably more structured in how it represents the search results and subresults, notably on how they group the search results.

The blog we used as reference for the styling formats the pagefindresults by processing the search results. More information on how to access the specific search results information can be found here.

  1. Added pagefind configuration options within site.json to enable more flexible filtering options. Users can declare
    • exclude_selectors option to exclude specific elements from being searchable.
    • glob option to limit which pages are indexed by Pagefind.
{
"pagefind": {
"exclude_selectors": [".algolia-no-index", "[class*='algolia-no-index']"]
"glob": ["**/devGuide/**", "**/userGuide/**"]
}
}
  • from the example above,
    • exclude_selectors: tells Pagefind to exclude any element with the algolia-no-index class from the searchable results. It works the same way as declaring data-pagefind-ignore.
    • glob: Pagefind will only index pages that are found inside devGuide and userGuide directories (including subdirectories).

All in all, theres still a lot more things we can do to improve this pagefind feature (like page weighting, ranking, sortingetc). But this is all I've managed to conjure up thus far.

Let me know what yall think of these updates to the pagefind feature (there might be better ways to filter pages, this is just from my interpretation when reading through the pagefind docs). Let me know if I missed out on anything in particular or should be focusing my efforts more towards.

  • Definitely going to spend more time working on the styling. But I think if we're gonna process and present our data differently from the base Pagefind UI, then we should probably work on those at the same time since they are intrinsically linked.
  • Also needa write testcases 😔. Not looking forward to that 😢

Testing instructions:

Proposed commit message: (wrap lines at 72 characters)

Add base Pagefind with updated UI & extra filtering functionalities


Checklist: ☑️

  • Updated the documentation for feature additions and enhancements
  • Added tests for bug fixes or features
  • Linked all related issues
  • No unrelated changes

Reviewer checklist:

Indicate the SEMVER impact of the PR:

  • Major (when you make incompatible API changes)
  • Minor (when you add functionality in a backward compatible manner)
  • Patch (when you make backward compatible bug fixes)

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):

  • To be included in the release note for any feature that is made obsolete/breaking

Give a brief explanation note about:

  • what was the old feature that was made obsolete
  • any replacement feature (if any), and
  • how the author should modify his website to migrate from the old feature to the replacement feature (if possible).

This added support for configuring Pagefind search indexing via
site.json is aimed towards allowing users to declare glob patterns to
customize what pages in which directory should be indexed by pagefind.
Initially, I felt that including the root_selector option and
force_language option would be useful for pagefind configuration
options. But perhaps for now it isn't the most pressing issue so I'm
going to exlcude it from the current implementation of pagefind.
This helps resolve an issue with generate() test case within
Site.functional.test.ts. Namely, because Jest's cannot intercept
eval('import("pagefind")') runtime dynamic import used by pagefind.
Hence, for now at least, the error handling would catch this error and
allow the site generation to continue normally.
Extracted processResult into its own helper function.
Added rel="noopener noreferrer" attribute for improved security and
privacy when being redirected to pagefind's github repo.
@codecov

codecovBot commented Mar 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.18321% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.88%. Comparing base (64c1dca) to head (0b71c41).
⚠️ Report is 1 commits behind head on master.

Files with missing linesPatch %Lines
packages/core/src/Site/SiteGenerationManager.ts96.00%3 Missing ⚠️
packages/core/test/unit/utils/data.ts83.33%2 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #2857 +/- ##
==========================================
+ Coverage 70.41% 70.88% +0.47% 
==========================================
Files 129 131 +2 Lines 6952 7083 +131 Branches 1578 1660 +82 ==========================================
+ Hits 4895 5021 +126 - Misses 1957 1962 +5 
Partials 100 100 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@MoshiMoshiMochi

MoshiMoshiMochi commented Mar 19, 2026

Copy link
Copy Markdown
ContributorAuthor

Hi guys, sorry for the wait, marking this as ready to review!

As mentioned in the PR description, while I believe there are still plenty of things that we can work on to enhancing the Pagefind feature in the future.

Namely, we could take a look at

  1. Creating a subsection for our results (similar to how algolia does it, as discussed in last week's meeting). I kinda have an idea of how to extract and process the results information so definitely will work on this as soon as this PR is merged.

  2. Get it to work on hot reloading

We can probably make separate issues for these things.

The current implementation is far from perfect (e.g. a lot of css can be improved, clearly still an issue when using at different browser sizes, also a lot of z level issues with the navbar & nav components).

So let me know of what yall think of the current implementation, anything to improve, anything pressing to fix, etc.

@MarkBind/active-3281-members

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Pagefind-based full-text search to MarkBind as a beta feature, including build-time indexing, asset injection into generated pages, a new Vue <search /> modal UI, and supporting configuration/docs/test updates.

Changes:

  • Introduce a new Vue Search component (Pagefind UI modal) and styling assets.
  • Generate and inject Pagefind search assets during site generation, with site.json support for pagefind.exclude_selectors and pagefind.glob.
  • Update unit/functional tests, expected HTML outputs, and tooling ignores to accommodate generated Pagefind artifacts.

Reviewed changes

Copilot reviewed 128 out of 130 changed files in this pull request and generated 10 comments.

Show a summary per file
FileDescription
packages/vue-components/src/pagefindSearchBar/assets/search.cssAdds global CSS for the Pagefind search modal styling.
packages/vue-components/src/pagefindSearchBar/Search.vueNew Pagefind-backed search modal component + keyboard handling and UI overrides.
packages/vue-components/src/pagefindSearchBar/LogoPagefind.vueAdds Pagefind logo SVG for the modal footer.
packages/vue-components/src/index.jsRegisters the new Search component for <search /> usage.
packages/vue-components/src/tests/Search.spec.jsAdds unit tests for the new Search component behavior.
packages/core/test/unit/utils/data.tsAdds factories/helpers for mocking Pagefind and generating site.json with Pagefind config.
packages/core/test/unit/Site/SiteGenerationManager.test.tsAdds unit tests for Pagefind glob normalization/validation and indexing behavior.
packages/core/src/Site/SitePagesManager.tsInjects Pagefind UI CSS/JS asset paths into page rendering assets when search is enabled.
packages/core/src/Site/SiteGenerationManager.tsAdds Pagefind indexing during site generation and glob filtering support.
packages/core/src/Site/SiteConfig.tsExtends site config to include optional pagefind configuration.
packages/core/src/Page/page.njkInjects Pagefind UI stylesheet/script into generated pages when available.
packages/core/src/Page/PageConfig.tsAdds pagefindCss/pagefindJs to PageAssets type.
packages/core/package.jsonAdds pagefind dependency for build-time indexing.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/UserGuide.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/QuickStart.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/Features.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/FAQ.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/team/johndoe.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/team/AboutUs.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/TracingCode.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Testing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/SettingUp.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Requirements.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Implementation.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Documentation.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/DeveloperGuide.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/DevOps.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Design.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Configuration.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_portfolio/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_minimal/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_table_plugin/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_special_tags/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_3.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/about.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/README.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/Page-1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/Home.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/about.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/_Sidebar.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/_Footer.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/Page-1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/Home.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_algolia_plugin/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/test_md_fragment.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testWeb3FormPlugin.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testVariableContainsInclude.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testTree.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testTooltipSpacing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testThumbnails.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testSourceContainScript.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testSingleAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPopovers.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPopoverTrigger.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPlantUML.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanelsClosingTransition.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanels.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanelMarkdownParsing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavWithoutTitleAndNavHeadings.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavWithOnlyTitle.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavTarget.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavPrint.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNav.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testOcticonInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testModals.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMermaid.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMath.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMaterialIconsInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testList.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLinks.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsWithAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsOverrideWithAltFrontmatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsOverride.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayouts.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludePluginsRendered.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludeMultipleModals.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludeBoilerplate.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testImages.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIconsInSiteLayout.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testHr.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testGlyphiconInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testFontAwesomeInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testExternalScripts.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testEmptyFrontmatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testEmptyAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testDates.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testCodeBlocks.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testCenterText.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testBootstrapIconInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAntiFOUCStyles.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAnnotate.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAnchorGeneration.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAltFrontMatterParsing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAltFrontMatterInvalidKeyValue.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/nested_sub_site/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/nested_sub_site/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/bugs/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/testUtil/compare.tsAdds ignore support for generated Pagefind outputs in functional comparisons.
packages/cli/test/functional/test.tsUses new compare() signature to ignore generated pagefind/ directories.
package-lock.jsonLocks Pagefind and platform-specific optional dependencies.
docs/userGuide/makingTheSiteSearchable.mdDocuments Pagefind beta usage and new site.json options.
.stylelintrc.jsAdds stylelint override for Pagefind UI class naming patterns.
.gitignoreIgnores generated Pagefind directories and fragments.
.eslintrc.jsAdds ESLint ignore patterns for generated/build output directories.
.eslintignoreIgnores generated Pagefind JS under functional test outputs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/core/src/Site/SitePagesManager.ts Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/assets/search.css Outdated
Comment threadpackages/core/src/Site/SiteGenerationManager.ts

@Harjun751Harjun751 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huge effort, and it definitely paid off!

Requesting some changes/clarifications for the

  • debug.log file
  • empty glob parsing
  • windows directory safety check
  • spawned watcher

issues, but other than that it's all minor nits. After the above I think we'll be in a good state.

Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threadpackages/core/src/Page/PageConfig.ts
Comment threadpackages/core/src/Site/SitePagesManager.ts Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts Outdated
Now indexSiteWithPagefind returns a boolean which is then determines if
there is a need to inject the pagefindcss & pagefindJs.
Since isValidGlobPattern is only used by normalizeGlobPattern, changed
it to private access. Now normalization of pattern happens solely in
normalizeGlobPattern and validation is purely a validation method.
Better separation of concerns.
Also resolved a bug where the 404s required pages to be created before
knowing if indexing succeeds by defaulting index success to true and
only if it fails does the flag get set to false.
@gerteck

gerteck commented Mar 22, 2026

Copy link
Copy Markdown
Member

I tried dropping the default pagefind-ui.css and realized the search component is depending on it quite heavily

image

Comment threaddocs/userGuide/makingTheSiteSearchable.md
@gerteck

Copy link
Copy Markdown
Member

Good first step introducing pagefind into MarkBind @MoshiMoshiMochi . The build-time integration (Node API, createIndex/addDirectory/writeFiles, glob support, exclude_selectors config) is solid and the right approach.

The main concern is in Search.vue. The current implementation wraps window.PagefindUI — a pre-built UI component that injects its own DOM, inside a custom modal shell, then works against PagefindUI's behaviour to get the desired result:

  • ~70 lines of :deep(.pagefind-ui__*) CSS overrides to fight PagefindUI's default styles
  • A MutationObserver to detect when PagefindUI renders results (needed because Search.vue has no direct control over PagefindUI's rendering
    lifecycle)
  • Custom keyboard navigation running alongside PagefindUI's own keyboard handling
  • container.innerHTML = '' on modal close as a teardown workaround (PagefindUI has no destroy API)
  • Silent failure if window.PagefindUI is undefined (script load error goes unnoticed)

This is workable for a first cut, but the cause-and-effect is opaque, where future contributors would need to understand both the PagefindUI internals and overrides to make changes safely. It also loads pagefind-ui.js (84.6KB) + pagefind-ui.css (14.5KB) on every page, when we only need pagefind.js (33.8KB).

The long-term direction should be:

  • Replace window.PagefindUI with the lower-level pagefind.js API, which lets you query the index directly and returns plain data objects
  • Ideally, Search.vue owns all the DOM natively as Vue reactive state — no CSS overrides, no MutationObserver, no innerHTML teardown, no global window dependency.

Suggest tracking this as follow-up issues:

  1. Replace window.PagefindUI with pagefind.js lower-level API — remove the <script src="pagefind-ui.js"> global, dynamically import pagefind.js inside the component instead
  2. In-house result rendering — render results natively in the Vue template (title, excerpt, sub-results, active highlight) instead of delegating to PagefindUI's DOM
  3. In-house CSS — replace :deep() overrides with first-party styles scoped to our own markup

I think it is okay to approve as a foundation if these follow-ups are tracked, since the build-time indexing is correct and the search does work end-to-end, just wanted to clarify on your architectural direction for the component moving forward! @MoshiMoshiMochi

@Harjun751Harjun751 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes I requested are addressed 👍

@MoshiMoshiMochi
MoshiMoshiMochi merged commit 19b34fe into MarkBind:masterMar 25, 2026
10 checks passed
@github-actions

Copy link
Copy Markdown

@MoshiMoshiMochi Each PR must have a SEMVER impact label, please remember to label the PR properly.

@gerteckgerteck added the r.Minor Version resolver: increment by 0.1.0 label Mar 26, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

r.MinorVersion resolver: increment by 0.1.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@MoshiMoshiMochi@gerteck@Harjun751
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); Add PageFind beta V2 (Full Text Search across Site) by MoshiMoshiMochi · Pull Request #2857 · MarkBind/markbind · GitHub
Skip to content

Add PageFind beta V2 (Full Text Search across Site) - #2857

Merged
MoshiMoshiMochi merged 42 commits into
MarkBind:masterfrom
MoshiMoshiMochi:feat/pagefind-beta
Mar 25, 2026
Merged

Add PageFind beta V2 (Full Text Search across Site)#2857
MoshiMoshiMochi merged 42 commits into
MarkBind:masterfrom
MoshiMoshiMochi:feat/pagefind-beta

Conversation

@MoshiMoshiMochi

@MoshiMoshiMochiMoshiMoshiMochi commented Mar 11, 2026

Copy link
Copy Markdown
Contributor

What is the purpose of this pull request?

  • Documentation update
  • Bug fix
  • Feature addition or enhancement
  • Code maintenance
  • DevOps
  • Improve developer experience
  • Others, please explain:

Overview of changes:

Initial version of pagefind (based on #2771)

Original Search Issue is #205

No test cases yet.

Anything you'd like to highlight/discuss:

  1. Created a new Search.vue component <search /> that renders the pagefind search modal.
    • The CSS of which definitely isn't a finish product.
    • Additionally we could consider updating how we present the data.
Heres how the modal currently looks vs Algolia's (CS2103 site)

Current implementation of pagefind.
image

Algolia's styling on CS2103 website
image

From the 2 images above, I believe that Algolia's styling is notably more structured in how it represents the search results and subresults, notably on how they group the search results.

The blog we used as reference for the styling formats the pagefindresults by processing the search results. More information on how to access the specific search results information can be found here.

  1. Added pagefind configuration options within site.json to enable more flexible filtering options. Users can declare
    • exclude_selectors option to exclude specific elements from being searchable.
    • glob option to limit which pages are indexed by Pagefind.
{
"pagefind": {
"exclude_selectors": [".algolia-no-index", "[class*='algolia-no-index']"]
"glob": ["**/devGuide/**", "**/userGuide/**"]
}
}
  • from the example above,
    • exclude_selectors: tells Pagefind to exclude any element with the algolia-no-index class from the searchable results. It works the same way as declaring data-pagefind-ignore.
    • glob: Pagefind will only index pages that are found inside devGuide and userGuide directories (including subdirectories).

All in all, theres still a lot more things we can do to improve this pagefind feature (like page weighting, ranking, sortingetc). But this is all I've managed to conjure up thus far.

Let me know what yall think of these updates to the pagefind feature (there might be better ways to filter pages, this is just from my interpretation when reading through the pagefind docs). Let me know if I missed out on anything in particular or should be focusing my efforts more towards.

  • Definitely going to spend more time working on the styling. But I think if we're gonna process and present our data differently from the base Pagefind UI, then we should probably work on those at the same time since they are intrinsically linked.
  • Also needa write testcases 😔. Not looking forward to that 😢

Testing instructions:

Proposed commit message: (wrap lines at 72 characters)

Add base Pagefind with updated UI & extra filtering functionalities


Checklist: ☑️

  • Updated the documentation for feature additions and enhancements
  • Added tests for bug fixes or features
  • Linked all related issues
  • No unrelated changes

Reviewer checklist:

Indicate the SEMVER impact of the PR:

  • Major (when you make incompatible API changes)
  • Minor (when you add functionality in a backward compatible manner)
  • Patch (when you make backward compatible bug fixes)

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):

  • To be included in the release note for any feature that is made obsolete/breaking

Give a brief explanation note about:

  • what was the old feature that was made obsolete
  • any replacement feature (if any), and
  • how the author should modify his website to migrate from the old feature to the replacement feature (if possible).

This added support for configuring Pagefind search indexing via
site.json is aimed towards allowing users to declare glob patterns to
customize what pages in which directory should be indexed by pagefind.
Initially, I felt that including the root_selector option and
force_language option would be useful for pagefind configuration
options. But perhaps for now it isn't the most pressing issue so I'm
going to exlcude it from the current implementation of pagefind.
This helps resolve an issue with generate() test case within
Site.functional.test.ts. Namely, because Jest's cannot intercept
eval('import("pagefind")') runtime dynamic import used by pagefind.
Hence, for now at least, the error handling would catch this error and
allow the site generation to continue normally.
Extracted processResult into its own helper function.
Added rel="noopener noreferrer" attribute for improved security and
privacy when being redirected to pagefind's github repo.
@codecov

codecovBot commented Mar 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.18321% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.88%. Comparing base (64c1dca) to head (0b71c41).
⚠️ Report is 1 commits behind head on master.

Files with missing linesPatch %Lines
packages/core/src/Site/SiteGenerationManager.ts96.00%3 Missing ⚠️
packages/core/test/unit/utils/data.ts83.33%2 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## master #2857 +/- ##
==========================================
+ Coverage 70.41% 70.88% +0.47% 
==========================================
Files 129 131 +2 Lines 6952 7083 +131 Branches 1578 1660 +82 ==========================================
+ Hits 4895 5021 +126 - Misses 1957 1962 +5 
Partials 100 100 

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@MoshiMoshiMochi

MoshiMoshiMochi commented Mar 19, 2026

Copy link
Copy Markdown
ContributorAuthor

Hi guys, sorry for the wait, marking this as ready to review!

As mentioned in the PR description, while I believe there are still plenty of things that we can work on to enhancing the Pagefind feature in the future.

Namely, we could take a look at

  1. Creating a subsection for our results (similar to how algolia does it, as discussed in last week's meeting). I kinda have an idea of how to extract and process the results information so definitely will work on this as soon as this PR is merged.

  2. Get it to work on hot reloading

We can probably make separate issues for these things.

The current implementation is far from perfect (e.g. a lot of css can be improved, clearly still an issue when using at different browser sizes, also a lot of z level issues with the navbar & nav components).

So let me know of what yall think of the current implementation, anything to improve, anything pressing to fix, etc.

@MarkBind/active-3281-members

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Pagefind-based full-text search to MarkBind as a beta feature, including build-time indexing, asset injection into generated pages, a new Vue <search /> modal UI, and supporting configuration/docs/test updates.

Changes:

  • Introduce a new Vue Search component (Pagefind UI modal) and styling assets.
  • Generate and inject Pagefind search assets during site generation, with site.json support for pagefind.exclude_selectors and pagefind.glob.
  • Update unit/functional tests, expected HTML outputs, and tooling ignores to accommodate generated Pagefind artifacts.

Reviewed changes

Copilot reviewed 128 out of 130 changed files in this pull request and generated 10 comments.

Show a summary per file
FileDescription
packages/vue-components/src/pagefindSearchBar/assets/search.cssAdds global CSS for the Pagefind search modal styling.
packages/vue-components/src/pagefindSearchBar/Search.vueNew Pagefind-backed search modal component + keyboard handling and UI overrides.
packages/vue-components/src/pagefindSearchBar/LogoPagefind.vueAdds Pagefind logo SVG for the modal footer.
packages/vue-components/src/index.jsRegisters the new Search component for <search /> usage.
packages/vue-components/src/tests/Search.spec.jsAdds unit tests for the new Search component behavior.
packages/core/test/unit/utils/data.tsAdds factories/helpers for mocking Pagefind and generating site.json with Pagefind config.
packages/core/test/unit/Site/SiteGenerationManager.test.tsAdds unit tests for Pagefind glob normalization/validation and indexing behavior.
packages/core/src/Site/SitePagesManager.tsInjects Pagefind UI CSS/JS asset paths into page rendering assets when search is enabled.
packages/core/src/Site/SiteGenerationManager.tsAdds Pagefind indexing during site generation and glob filtering support.
packages/core/src/Site/SiteConfig.tsExtends site config to include optional pagefind configuration.
packages/core/src/Page/page.njkInjects Pagefind UI stylesheet/script into generated pages when available.
packages/core/src/Page/PageConfig.tsAdds pagefindCss/pagefindJs to PageAssets type.
packages/core/package.jsonAdds pagefind dependency for build-time indexing.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/UserGuide.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/QuickStart.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/Features.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/userGuide/FAQ.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/team/johndoe.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/team/AboutUs.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/TracingCode.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Testing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/SettingUp.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Requirements.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Implementation.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Documentation.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/DeveloperGuide.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/DevOps.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Design.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_project/expected/developerGuide/Configuration.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_portfolio/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_minimal/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_templates/test_default/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_table_plugin/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_special_tags/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_3.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/test_folder/extra_1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/about.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/README.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/Page-1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/Home.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_navigation_convert/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic3b.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic3a.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic2.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/contents/topic1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/about.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/_Sidebar.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/_Footer.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/Page-1.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/Home.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_convert/test_basic_convert/expected/404.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site_algolia_plugin/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/test_md_fragment.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testWeb3FormPlugin.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testVariableContainsInclude.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testTree.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testTooltipSpacing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testThumbnails.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testSourceContainScript.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testSingleAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPopovers.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPopoverTrigger.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPlantUML.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanelsClosingTransition.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanels.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPanelMarkdownParsing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavWithoutTitleAndNavHeadings.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavWithOnlyTitle.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavTarget.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNavPrint.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testPageNav.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testOcticonInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testModals.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMermaid.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMath.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testMaterialIconsInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testList.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLinks.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsWithAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsOverrideWithAltFrontmatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayoutsOverride.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testLayouts.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludePluginsRendered.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludeMultipleModals.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIncludeBoilerplate.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testImages.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testIconsInSiteLayout.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testHr.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testGlyphiconInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testFontAwesomeInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testExternalScripts.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testEmptyFrontmatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testEmptyAltFrontMatter.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testDates.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testCodeBlocks.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testCenterText.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testBootstrapIconInPage.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAntiFOUCStyles.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAnnotate.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAnchorGeneration.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAltFrontMatterParsing.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/testAltFrontMatterInvalidKeyValue.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/nested_sub_site/testNunjucksPathResolving.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/nested_sub_site/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/sub_site/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/test_site/expected/bugs/index.htmlUpdates expected HTML to include Pagefind UI assets.
packages/cli/test/functional/testUtil/compare.tsAdds ignore support for generated Pagefind outputs in functional comparisons.
packages/cli/test/functional/test.tsUses new compare() signature to ignore generated pagefind/ directories.
package-lock.jsonLocks Pagefind and platform-specific optional dependencies.
docs/userGuide/makingTheSiteSearchable.mdDocuments Pagefind beta usage and new site.json options.
.stylelintrc.jsAdds stylelint override for Pagefind UI class naming patterns.
.gitignoreIgnores generated Pagefind directories and fragments.
.eslintrc.jsAdds ESLint ignore patterns for generated/build output directories.
.eslintignoreIgnores generated Pagefind JS under functional test outputs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/core/src/Site/SitePagesManager.ts Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/assets/search.css Outdated
Comment threadpackages/core/src/Site/SiteGenerationManager.ts

@Harjun751Harjun751 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huge effort, and it definitely paid off!

Requesting some changes/clarifications for the

  • debug.log file
  • empty glob parsing
  • windows directory safety check
  • spawned watcher

issues, but other than that it's all minor nits. After the above I think we'll be in a good state.

Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threaddocs/userGuide/makingTheSiteSearchable.md
Comment threadpackages/core/src/Page/PageConfig.ts
Comment threadpackages/core/src/Site/SitePagesManager.ts Outdated
Comment threadpackages/vue-components/src/pagefindSearchBar/Search.vue Outdated
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts
Comment threadpackages/core/src/Site/SiteGenerationManager.ts Outdated
Now indexSiteWithPagefind returns a boolean which is then determines if
there is a need to inject the pagefindcss & pagefindJs.
Since isValidGlobPattern is only used by normalizeGlobPattern, changed
it to private access. Now normalization of pattern happens solely in
normalizeGlobPattern and validation is purely a validation method.
Better separation of concerns.
Also resolved a bug where the 404s required pages to be created before
knowing if indexing succeeds by defaulting index success to true and
only if it fails does the flag get set to false.
@gerteck

gerteck commented Mar 22, 2026

Copy link
Copy Markdown
Member

I tried dropping the default pagefind-ui.css and realized the search component is depending on it quite heavily

image

Comment threaddocs/userGuide/makingTheSiteSearchable.md
@gerteck

Copy link
Copy Markdown
Member

Good first step introducing pagefind into MarkBind @MoshiMoshiMochi . The build-time integration (Node API, createIndex/addDirectory/writeFiles, glob support, exclude_selectors config) is solid and the right approach.

The main concern is in Search.vue. The current implementation wraps window.PagefindUI — a pre-built UI component that injects its own DOM, inside a custom modal shell, then works against PagefindUI's behaviour to get the desired result:

  • ~70 lines of :deep(.pagefind-ui__*) CSS overrides to fight PagefindUI's default styles
  • A MutationObserver to detect when PagefindUI renders results (needed because Search.vue has no direct control over PagefindUI's rendering
    lifecycle)
  • Custom keyboard navigation running alongside PagefindUI's own keyboard handling
  • container.innerHTML = '' on modal close as a teardown workaround (PagefindUI has no destroy API)
  • Silent failure if window.PagefindUI is undefined (script load error goes unnoticed)

This is workable for a first cut, but the cause-and-effect is opaque, where future contributors would need to understand both the PagefindUI internals and overrides to make changes safely. It also loads pagefind-ui.js (84.6KB) + pagefind-ui.css (14.5KB) on every page, when we only need pagefind.js (33.8KB).

The long-term direction should be:

  • Replace window.PagefindUI with the lower-level pagefind.js API, which lets you query the index directly and returns plain data objects
  • Ideally, Search.vue owns all the DOM natively as Vue reactive state — no CSS overrides, no MutationObserver, no innerHTML teardown, no global window dependency.

Suggest tracking this as follow-up issues:

  1. Replace window.PagefindUI with pagefind.js lower-level API — remove the <script src="pagefind-ui.js"> global, dynamically import pagefind.js inside the component instead
  2. In-house result rendering — render results natively in the Vue template (title, excerpt, sub-results, active highlight) instead of delegating to PagefindUI's DOM
  3. In-house CSS — replace :deep() overrides with first-party styles scoped to our own markup

I think it is okay to approve as a foundation if these follow-ups are tracked, since the build-time indexing is correct and the search does work end-to-end, just wanted to clarify on your architectural direction for the component moving forward! @MoshiMoshiMochi

@Harjun751Harjun751 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes I requested are addressed 👍

@MoshiMoshiMochi
MoshiMoshiMochi merged commit 19b34fe into MarkBind:masterMar 25, 2026
10 checks passed
@github-actions

Copy link
Copy Markdown

@MoshiMoshiMochi Each PR must have a SEMVER impact label, please remember to label the PR properly.

@gerteckgerteck added the r.Minor Version resolver: increment by 0.1.0 label Mar 26, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

r.MinorVersion resolver: increment by 0.1.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@MoshiMoshiMochi@gerteck@Harjun751