v1.2.6
Search
npm run build writes a search index under site/api/ and bundles a React runtime that mounts
into the <Search /> placeholder or [data-canopy-search]. Works (IIIF manifests) and pages (MDX
files) share a single FlexSearch store so filters and type tabs stay in sync.
Data sources
- Works — every manifest pulled from
collectionURIs becomes atype: 'work'record withid,title, andhrefpointing at/works/<slug>.html. Metadata fields listed insearch.index.metadataare flattened for indexing. - Pages — MDX files contribute
type: 'page'records when they have no front matter or when they explicitly settype. Addsearch: falseto opt out. OptionalsearchSummaryandsearchSummaryMarkdownfields override the teaser.
packages/app/lib/build/search-index.js combines the records and keeps IDs stable between
search-index.json (FlexSearch input) and search-records.json (display data).
Page composition
Create content/search/_layout.mdx to control the markup surrounding the runtime. The layout
receives a search prop with form, summary, count, and results placeholders. Drop them
anywhere in the document to change the layout without editing React code.
---title: Search--- <section> <h1>{props.title}</h1> {props.search.summary} {props.search.form} {props.search.count}</section> {props.search.results}If you omit _layout.mdx, Canopy renders a fallback layout that stacks the form, summary, and
results vertically.
Tabs, layouts, and templates
Control the rendered tabs and markup via search.results in canopy.yml:
search: results: work: layout: grid # grid | list result: figure # figure | article page: layout: list result: article tabs: order: - work - pagelayoutswitches between the masonry grid (usesreact-masonry-css) and a stacked list.resultpicks the MDX partial that renders each item. Define_result-figure.mdxor_result-article.mdxundercontent/search/to override the defaults. Each file receives the record (props.record), the active query, and helper props for badges or metadata.tabs.orderreorders tabs without redefininglayout/result. Types omitted fromresultsinherit the defaultgrid+figurecombo.
Filtering and URL state
The runtime watches ?q and ?type query params, so deep links remain stable when you switch
between tabs or refine a search. When you add more record types via front matter (searchType: example), include them in search.results and tabs.order to expose dedicated tabs.
Styling hooks
- Use the
.canopy-searchclass (root element) to add custom spacing or background treatments inapp/styles/main.css. - Override button or input styles globally via the Tailwind preset or your own CSS variables in
@theme. - When you need different markup for specific record types, create additional templates under
content/search/and branch based onrecord.typeinside the MDX.
Debugging tips
- Inspect
site/api/search-index.jsonto confirm front-matter summaries and metadata labels are being indexed. - When the browser console logs
Dynamic require of 'react' is not supported, make sure the UI build marksreact,react-dom,react-dom/client,react-masonry-css, andflexsearchas externals (the repository is already configured this way). - Delete
.cache/search(if present) plussite/api/search-*and rebuild when you change record shapes.
Metadata browse
Canopy builds /metadata automatically. It groups the metadata labels you list in canopy.yml
(metadata array) and renders links to every unique value found across the ingested manifests. Each
link jumps directly to search results filtered to that label/value pair.
metadata: - Subject - Creator - Date - LocationDuring the IIIF build, Canopy generates /api/facet/<label>/<value>.json collections for those
labels. The metadata page uses the files to calculate counts and to build the links used elsewhere
(home sliders, related items, search filters).
Page anatomy
- Intro copy —
content/metadata/index.mdxcontrols the opening paragraph and any contextual guidance you want to provide to visitors. - Facet sections — For each configured label Canopy shows the heading and a list of values,
ordered by descending occurrence. Each value links to
/search?type=work&label=<label>&value=<value>. - Counts — Values display the number of works that match the label/value pair so users can gauge scale before clicking through.
Editing tips
- Keep facet labels short and consistent; the UI uses the label verbatim as the section heading.
- Remove labels from
canopy.ymlwhen you stop using them to avoid generating unused/api/facet/**files. - Pair metadata browse sections with MDX essays that explain curatorial choices. Cite those works
via
referencedManifestsso the relationship flows back to individual work pages.