Skip to content

The search as one block ​

Build the search layout and its components once, and place them as one block on as many pages as needed.

When to prefer it ​

  • The same search shows on several pages, e.g., a recipe search on each recipe category page.
  • Editors should place one block, not a layout section and a dozen blocks.
  • Editors manage the content around the search without the ability to modify the search.
  • The search should be deployed as one piece, built once and placed where needed.

Drawbacks ​

  • The components cannot be moved on a page. Only the whole block is placed, and moving the pager or adding a facet is a change to the block.
  • A change to one component changes every page that has the block.
  • With a block plugin, the search is code. Changing it takes a developer and a deployment.

How ​

There are two approaches: a block type, where the search is content, and a block plugin, where the search is code.

A block type with Layout Builder ​

The search is a content block of a block type that uses Layout Builder. The block type's layout holds the search, and each content block of that type shows it.

The search needs:

  • Layout Builder and Search Web Components: Layouts enabled
  • a block type with Layout Builder on its Default display and Allow each content block to have its layout customized. unchecked

If the site already has such a block type, go on to step 3.

  1. On Structure › Block types, click Add block type. Enter a label, e.g., "Search", and click Save.

  2. On the block type's Manage display tab, click Manage (Default). Under Layout options, check Use Layout Builder. Leave Allow each content block to have its layout customized. unchecked. Click Save.

  3. On the block type's Manage display tab, click Manage (Default), then Manage layout.

  4. Click Add section and pick Search Components: Two Column. Under Decoupled Search Endpoint, pick the endpoint. Set Default results per page to the endpoint's Limit, and click Add section.

  5. In each region, click Add block and pick the block from Search Components:

    • Top First: Search Input
    • Left First: Facet: Checkbox
    • Right First: Results
    • Right Second: Simple Pager

    For each block's settings, see Layout Builder.

  6. Click Save layout.

  7. Add a content block of the new type, e.g., "Recipe search".

  8. Place the Recipe search block where the search shows: on Structure › Block layout in a region, with the pages it shows on under Visibility › Pages, in a section of a page that uses Layout Builder, or on a Drupal Canvas page.

A block plugin with a template ​

The search is a block plugin in a custom module. The block has a template with a search layout component and the search components, so the whole search is code and deploys with the module. This example is a module named my_search with a block Recipe search: a two-column search with /api/search/content as its endpoint, a keyword field, a sort, one facet, the results, and a pager.

  1. my_search.info.yml:

    yaml
    name: 'My search'
    type: module
    description: 'The recipe search as one block.'
    package: Custom
    core_version_requirement: ^10.3 || ^11 || ^12
    dependencies:
      - search_web_components:search_web_components
  2. my_search.module, with the theme hook the block renders through:

    php
    <?php
    
    /**
     * Implements hook_theme().
     */
    function my_search_theme(): array {
      return [
        'recipe_search' => [
          'variables' => [],
        ],
      ];
    }
  3. src/Plugin/Block/RecipeSearchBlock.php:

    php
    <?php
    
    declare(strict_types=1);
    
    namespace Drupal\my_search\Plugin\Block;
    
    use Drupal\Core\Block\Attribute\Block;
    use Drupal\Core\Block\BlockBase;
    use Drupal\Core\StringTranslation\TranslatableMarkup;
    
    /**
     * The recipe search: a search layout with its components.
     */
    #[Block(
      id: 'recipe_search',
      admin_label: new TranslatableMarkup('Recipe search'),
      category: new TranslatableMarkup('Search'),
    )]
    final class RecipeSearchBlock extends BlockBase {
    
      /**
       * {@inheritdoc}
       */
      public function build(): array {
        return ['#theme' => 'recipe_search'];
      }
    
    }
  4. templates/recipe-search.html.twig. Set defaultPerPage to the endpoint's Limit and key on the facet to the facet's machine name. The sort options, page sizes, and result elements come from the endpoint:

    twig
    {{ include('search_web_components:search-layout-two-column', {
      url: '/api/search/content',
      defaultPerPage: '10',
      topOne: {
        '#type': 'component',
        '#component': 'search_web_components:search-input',
        '#props': {placeHolderText: 'Search recipes'|t},
      },
      topTwo: {
        '#type': 'component',
        '#component': 'search_web_components:search-sort',
        '#props': {type: 'select', labelText: 'Sort by'|t},
      },
      sidebarOne: {
        '#type': 'component',
        '#component': 'search_web_components:facet-checkbox',
        '#props': {key: 'recipe_category'},
      },
      mainOne: {
        '#type': 'component',
        '#component': 'search_web_components:search-results',
      },
      mainTwo: {
        '#type': 'component',
        '#component': 'search_web_components:search-simple-pager',
        '#props': {ariaLabelText: 'Pages'|t},
      },
    }, with_context = false) }}
  5. Enable the module. Place the Recipe search block where the search shows: on Structure › Block layout in a region, with the pages it shows on under Visibility › Pages, in a section of a page that uses Layout Builder, or on a Drupal Canvas page.

For the slots and how they are filled, see The layout components. For each component's props, see its page in Storybook.