Skip to content

Customizing in Drupal code ​

Each kind of change to a component has its own place:

To changeUseMore
A value, e.g., a label or the sort optionsThe block's settings, the component's props in Canvas, or the props of a Twig includeLayout Builder, Drupal Canvas, Placing components from Twig
The props of one placed blockhook_preprocess_block()The props of one placed block
The attributes or wrapper markup of a component everywhereA theme component with replaces:The markup of a component everywhere
What the element renders insideA subclassA subclass on a Drupal page, Extend for the hooks
What the root sends and readsA search-root subclassSearching another API
How it looksCSSStyling

The props of one placed block ​

To change the props of one block, implement hook_preprocess_block() in a module or theme. The hook runs for blocks in the block layout and in Layout Builder:

php
function example_theme_preprocess_block(array &$variables): void {
  if ($variables['plugin_id'] === 'swc_search_sort') {
    $variables['content']['#props']['labelText'] = t('Order by');
  }
}

The markup of a component everywhere ​

Every component is a single directory component, search_web_components:<tag>. Its template prints the custom element tag with its attributes, and the element renders the markup inside the tag in the browser.

To change that template everywhere, add a component to your theme with replaces: search_web_components:<tag> and the same props, e.g., components/search-results-switcher/search-results-switcher.component.yml:

yaml
name: Search results switcher
status: stable
replaces: 'search_web_components:search-results-switcher'
props:
  type: object
  properties:
    options:
      title: Options
      type: array
      items:
        type: object
      examples:
        - [{key: list, label: List}]

Its template starts as a copy of the module's, components/<tag>/<tag>.twig.

A subclass on a Drupal page ​

The Search Web Components module loads the bundle on every page that has a component, as the library search_web_components/components. A subclass takes its base class from window.SearchWebComponents and goes in a library that depends on that one, so it runs after the bundle:

js
const {SearchSort} = window.SearchWebComponents;

class RecipeSort extends SearchSort {
  constructor() {
    super();
    this.labelText = 'Order by';
  }
}
customElements.define('recipe-sort', RecipeSort);

A render() override, or a result element with markup of its own, takes Lit's template helpers from window.SearchWebComponents.lit. A reactive attribute is declared in static properties, as there is no build step to run decorators:

js
const {BaseSearchElement, lit} = window.SearchWebComponents;
const {html} = lit;

class RecipeCardResult extends BaseSearchElement {
  static properties = {data: {type: Object}};

  render() {
    return html`<a href=${this.data.url}>${this.data.title}</a>`;
  }
}
customElements.define('recipe-card-result', RecipeCardResult);
yaml
recipe_sort:
  js:
    js/recipe-sort.js: {attributes: {type: module}}
  dependencies:
    - search_web_components/components

For what window.SearchWebComponents holds, see Install.

The page then needs the subclass's tag and the library:

  • In a template of your own, print <recipe-sort> and attach the library.

  • In a theme component that replaces: search_web_components:search-sort, print <recipe-sort> in its template and attach the library from the component.

  • For a search-root subclass, use a layout or template of your own that renders the subclass's tag with the attributes search-root takes. The Search Web Components layouts render <search-root>.

  • For a result element the endpoint's result elements map to, no template of yours is in the page, so make your library a dependency of the search-results component's library in hook_library_info_alter(). The Results block, a Canvas page, and a Twig template all render results through that component, so the element is defined wherever results are:

    php
    function example_library_info_alter(array &$libraries, string $extension): void {
      if ($extension === 'core' && isset($libraries['components.search_web_components--search-results'])) {
        $libraries['components.search_web_components--search-results']['dependencies'][] = 'example/recipe_card_result';
      }
    }

For the hooks a subclass overrides, see Extend. For a root that searches another API, see Searching another API.

Block defaults that differ from the element ​

A component placed from Twig or Canvas uses the element's defaults. The blocks set these attributes to defaults of their own. To make a component placed from Twig or Canvas match the block, set them:

BlockAttributeBlock defaultElement default
Search InputlabelTextSearchempty
Search InputplaceHolderTextSearchempty
SortlabelTextSort bySort
SorthtmlSelectLabelSort byChoose an option
Results per pagehtmlSelectLabelPer pageChoose an option
Simple PagershowNextPrevonoff
Simple PagerfirstLabelFirstFirst page
Simple PagerlastLabelLastLast page
Applied FacetsresetTextResetReset (@count)
Facet: Checkbox, Facet: Button, Facet: Dropdown, Facet: Dropdown HTMLshowCountonoff

A block setting left empty passes no attribute, so the element's default applies.