Appearance
Quickstart
At the end of this guide, a static HTML page searches a JSON file, with no build step. The guide needs Node.
The files
In an empty directory, install the package:
sh
npm init -y
npm install drupal-search-web-componentsSave the response below as response.json. This example response has only the keys the components require:
json
{
"search_results": [
{"id": "1", "title": "Tomato soup", "url": "/recipes/tomato-soup"},
{"id": "2", "title": "Lentil curry", "url": "/recipes/lentil-curry"},
{"id": "3", "title": "Cooking with lentils", "url": "/articles/lentils"}
],
"search_results_count": 3,
"search_results_page": 0,
"search_results_pages": 1,
"search_results_per_page": 10,
"facets": [
{
"key": "type",
"label": "Type",
"count": 2,
"results": [
{"key": "recipe", "label": "Recipe", "count": 2, "children": [], "in_active_trail": false, "children_expanded": false},
{"key": "article", "label": "Article", "count": 1, "children": [], "in_active_trail": false, "children_expanded": false}
],
"settings": {"url_alias": "type", "widget": {}}
}
]
}Save the search page as index.html:
html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Search</title>
<script type="module">
// Shows one result as a link to it.
class TitleLinkResult extends HTMLElement {
set data(result) {
const link = document.createElement('a');
link.href = result.url;
link.textContent = result.title;
this.replaceChildren(link);
}
}
customElements.define('title-link-result', TitleLinkResult);
</script>
<script
type="module"
src="./node_modules/drupal-search-web-components/search-web-components.min.js"
></script>
</head>
<body>
<search-root url="/response.json" defaultPerPage="10">
<search-input labelText="Search"></search-input>
<facet-checkbox key="type" showLabel showCount></facet-checkbox>
<search-result-summary></search-result-summary>
<search-results
mappings='[{"keys":["default"],"element":"title-link-result","settings":{}}]'
></search-results>
</search-root>
</body>
</html>Serve the directory and open http://localhost:3000/:
sh
npx serveThe page shows the three results as links and the Type facet with its counts. The summary reads 1 - 3 of 3. Checking Recipe writes ?f[type]=recipe to the page URL. A keyword writes ?q=. The static file answers every search with the same response, so a keyword or a checked facet changes the URL and not the results. A working search page needs an endpoint that answers each request: the endpoint of the Drupal module, or another API, see Searching another API.
What the page does
search-rootsearches. It sends every search to itsurlas a GET request and gets a JSON response. The components inside it render that response, and what a visitor does with them, e.g., a keyword typed or a facet checked, starts the next search. For the request and the response, see Concepts.search-inputandfacet-checkboxchange the search. The facet shows the entry of the response'sfacetswith itskey. When a visitor checks an option, the next request filters by it.search-resultsrenders each result with a result element. A result element is a custom element, one of the shipped ones or your own:search-resultssets the result on itsdataproperty and the mapping's settings on itssettingsproperty, and the element renders the result. Search Web Components ships two:search-result-element-rendered, which prints a result field's HTML, andsearch-result-element-default, which prints the result as JSON. This example defines a third,title-link-result, which prints the title as a link.mappingsnames the element to use, here for every result. For writing one, see Custom result elements.- Attribute names are camelCase. Write them as the component pages list them, e.g.,
defaultPerPage. A kebab-case name, e.g.,default-per-page, is ignored, with no warning.
A richer page in Storybook
The Headless story in Storybook is a page like this one, on a mock endpoint that sends only the required keys, with sorting, page sizes, listing layouts, a pager, and the result element set by attributes. Open it in Storybook to read its attributes and change them.