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
pages → name, 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
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.
Scope (v1)
Global site search across all published pages + CMS content. (Per-collection search can build on the same foundation later.)
Indexable content sources
pages→name,settings.seo.title,settings.seo.description,slugpage_layers.layers→ walkvariables.text(flatten Tiptap),variables.image.alt, component overridescollection_item_values.value→ text / rich_text fields for dynamic pages and collection layerstranslations→ localized variants of the aboveProposed implementation surface
Closest existing analog: the
filterelement +FilterableCollection.searchelement template (lib/templates/) + entry inElementLibrary.tsxapp/(builder)/ycode/api/publish/route.ts), reusingextractLayerContentMap,tiptap-utils,text-format-utilsLayerRendererPublic.tsx(mirror inLayerRenderer.tsx), loaded as a dynamic import like other behaviorsOpen design question
Indexing/query approach is undecided and needs a design decision:
./out).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)