Skip to content

feat: add site search component for published sites #306

Description

@ysamcode

Summary

Add a global Site Search feature so visitors can search across a published Ycode site (pages and CMS content) — similar to what some other website builders offer. Today Ycode has no site-wide search; only editor/CMS filtering and a per-collection filter element exist.

Background — how some other website builders do it

Some other website builders ship a drag-in Search component (Insert panel) that indexes the site at publish/optimization time and runs a client-side fuzzy search (Fuse.js-style) on the published site, so results are instant with no server round-trip.

  • Indexes body copy, headings, page titles, and page descriptions
  • Scope control (whole site, specific paths, or a single CMS collection)
  • Layout presets: Quick Menu (command palette), Sidebar, Fixed Top

Scope (v1)

Global site search across all published pages + CMS content. (Per-collection search can build on the same foundation later.)

Indexable content sources

  • pagesname, settings.seo.title, settings.seo.description, slug
  • page_layers.layers → walk variables.text (flatten Tiptap), variables.image.alt, component overrides
  • collection_item_values.value → text / rich_text fields for dynamic pages and collection layers
  • translations → localized variants of the above

Proposed implementation surface

Closest existing analog: the filter element + FilterableCollection.

  • New search element template (lib/templates/) + entry in ElementLibrary.tsx
  • Build-time content extraction in the publish pipeline (app/(builder)/ycode/api/publish/route.ts), reusing extractLayerContentMap, tiptap-utils, text-format-utils
  • Runtime search behavior in LayerRendererPublic.tsx (mirror in LayerRenderer.tsx), loaded as a dynamic import like other behaviors
  • Scope control + layout preset as element settings

Open design question

Indexing/query approach is undecided and needs a design decision:

  • Build-time JSON index + client-side fuzzy search (Fuse.js): works on BOTH the live ISR site and the static HTML export (./out).
  • Server-side search API + Postgres full-text search: richer/scalable, but live-site only — would NOT work for static export.

Recommendation: lean toward the client-side index for static-export parity, but this should be confirmed before implementation. Note static export has no React hydration, so it needs a dedicated boot script in lib/apps/static-export/document.ts.

Out of scope (v1)

  • Per-collection-only search UI (future, builds on the same index)
  • Search analytics / "no results" tracking

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions