Skip to content

feat(search): add static Pagefind docs search#348

Open
bntvllnt wants to merge 2 commits into
mainfrom
feat/257-pagefind
Open

feat(search): add static Pagefind docs search#348
bntvllnt wants to merge 2 commits into
mainfrom
feat/257-pagefind

Conversation

@bntvllnt
Copy link
Copy Markdown
Collaborator

@bntvllnt bntvllnt commented May 13, 2026

Summary

  • Adds Pagefind as a registry-app dev dependency and runs search:index after next build, writing the generated bundle to ignored public/_pagefind.
  • Fixes the Turbo cache contract for the registry build by adding package-relative public/_pagefind/** to turbo.json build outputs, so the generated Pagefind bundle is part of cached/restored build artifacts.
  • Extends SearchDialog with Components, Docs, and Everything scopes, async docs results, keyboard-friendly command items, and highlighted snippets.
  • Removes the shipped eslint-disable-next-line max-lines-per-function suppression by splitting SearchDialog state/selection helpers into smaller functions, then regenerates the registry SearchDialog copy.
  • Regenerates component metadata and keeps the default story compatible with the required-props verifier.

Dependency tradeoff

Pagefind runs at build time and serves a static bundle, so this adds no hosted search service or runtime API dependency. The generated bundle is ignored and recreated during deploy builds, and public/_pagefind/** is now declared as a Turbo build output for artifact cache correctness.

Remediation notes

  • Current head: 39c73764c0ffbb49f8aff3f8d51d5b2ea7d14e7f
  • Pagefind cache blocker cleared: turbo.json build outputs include public/_pagefind/**.
  • SearchDialog lint-suppression blocker cleared: no eslint-disable remains in packages/ui/src/components/search-dialog/search-dialog.tsx or apps/registry/registry/default/search-dialog/search-dialog.tsx.
  • Registry copy was regenerated via pnpm -F @vllnt/ui-registry registry:build.

Notes

Validation

  • pnpm -F @vllnt/ui exec tsx scripts/verify-stories.ts — passed
  • pnpm -F @vllnt/ui lint — passed
  • pnpm -F @vllnt/ui exec tsc --noEmit --project tsconfig.build.json — passed
  • pnpm -F @vllnt/ui-registry exec tsc --noEmit --project tsconfig.json — passed
  • pnpm -F @vllnt/ui exec vitest run src/components/search-dialog/search-dialog.test.tsx — passed
  • pnpm build — passed; Pagefind v1.5.2 indexed 233 pages / 14222 words to public/_pagefind
  • pnpm test:once — passed; 217 files / 1217 tests
  • git diff --check — passed

Closes #257

@bntvllnt bntvllnt added enhancement New feature or request seo Search engine optimization discoverability Site/library discoverability labels May 13, 2026
@vercel
Copy link
Copy Markdown

vercel Bot commented May 13, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
storybook Ready Ready Preview, Comment May 14, 2026 2:04pm
ui.vllnt.ai Canceled Canceled May 14, 2026 2:04pm

Request Review

Copy link
Copy Markdown
Collaborator Author

@bntvllnt bntvllnt left a comment

Choose a reason for hiding this comment

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

Review — 2 blocking findings (REQUEST_CHANGES recommended)

BLOCKING

  • C1 — Pagefind output is missing from the cached build contract.

    • Evidence: apps/registry/package.json now runs next build && pnpm search:index and writes public/_pagefind, but turbo.json still declares registry build outputs as .next/**, dist/**, and public/r/** only. A cached registry build can therefore restore the Next artifact without restoring /_pagefind/pagefind.js, leaving the shipped docs-search UI with no Pagefind bundle.
    • Fix: add package-relative public/_pagefind/** to the Turbo build outputs, or move search indexing into an uncached deploy step that always runs before artifact collection.
  • R1 — shipped source includes a forbidden lint suppression.

    • Evidence: packages/ui/src/components/search-dialog/search-dialog.tsx adds // eslint-disable-next-line max-lines-per-function, and the registry copy mirrors it. docs/agents/COMPONENTS.md explicitly bans eslint-disable in shipped code.
    • Fix: split SearchDialog into smaller helpers/subcomponents or change the lint policy deliberately, then regenerate the registry copy.

VERIFIED CLEAN

  • Re-fetched live PR #348 immediately before publication: open, non-draft, head unchanged at 04f52393ba9d48982de82ffdaf36a3c63e41364a.
  • Rechecked the current diff anchors for both blockers at this head.
  • Prior full local coverage on this same head covered all 14 changed files; non-blocking validation was otherwise green.

VALIDATION

  • Current publication pass: gh pr view, pinned review worktree to the live head, inspected apps/registry/package.json, turbo.json, and packages/ui/src/components/search-dialog/search-dialog.tsx.
  • Not rerun in this publication pass: full workspace gates; relying on the earlier same-head validation evidence for non-blocking checks.

Note: GitHub rejected a formal REQUEST_CHANGES verdict because the authenticated reviewer is also the PR author, so this formal COMMENT review carries the blocking review gate instead.

"lint:fix": "eslint . --fix",
"registry:build": "tsx scripts/inline-component-source.ts && shadcn build && tsx scripts/stamp-registry-metadata.ts && tsx scripts/generate-component-metadata.ts",
"registry:sync-shims": "tsx scripts/inline-component-source.ts",
"search:index": "pagefind --site .next/server/app --output-path public/_pagefind --root-selector main --force-language en",
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Blocking: this adds search:index to generate public/_pagefind, but the registry build cache contract still omits public/_pagefind/** from Turbo outputs. A cached build can restore .next/** without restoring /_pagefind/pagefind.js, so the docs-search UI can ship with no Pagefind bundle. Add public/_pagefind/** to the package-relative Turbo build outputs, or make the search indexing step uncached and always run before deploy artifact collection.

);
}

// eslint-disable-next-line max-lines-per-function
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Blocking: shipped source cannot add eslint-disable. docs/agents/COMPONENTS.md explicitly bans eslint-disable; the registry copy mirrors this component too. Split SearchDialog into smaller helpers/subcomponents or change the lint policy deliberately, then regenerate the registry copy.

}

function stripMarkup(value: string) {
return value.replaceAll(/<[^>]*>/g, "");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

discoverability Site/library discoverability enhancement New feature or request seo Search engine optimization

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: full-text docs search (Pagefind, static, free)

2 participants