Skip to content

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-components

Save 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 serve

The 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-root searches. It sends every search to its url as 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-input and facet-checkbox change the search. The facet shows the entry of the response's facets with its key. When a visitor checks an option, the next request filters by it.
  • search-results renders each result with a result element. A result element is a custom element, one of the shipped ones or your own: search-results sets the result on its data property and the mapping's settings on its settings property, and the element renders the result. Search Web Components ships two: search-result-element-rendered, which prints a result field's HTML, and search-result-element-default, which prints the result as JSON. This example defines a third, title-link-result, which prints the title as a link. mappings names 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.